Where are template methods instantiated? - c++

In order to use an incomplete type with a smart pointer such as boost::scoped_ptr, one must explicitly define an empty destructor for the parent class in the corresponding CPP file. Example:
// H file
class Foo
{
public:
~Foo();
private:
class Pimpl;
boost::scoped_ptr<Pimpl> pimpl_;
};
// CPP file
class Foo::Pimpl {};
Foo::~Foo() {}
Where exactly does the compiler place the instantiation of boost::scoped_ptr's destructor? I'm trying to visually imagine where it would be in either of these source files, as if I had explicitly defined scoped_ptr's destructor myself. Is it reasonable to imagine it this way?
I know that template methods and classes aren't instantiated for a type until it is used with that type, but I'm trying to think about it structurally now, and where the compiler would place it if it actually hand-wrote it. This will help me get a better understanding of how such techniques (like the one above) are able to be used.
Also I'm not sure if the entire definition of a template class is instantiated or only the relevant parts of it, as they are used. In other words, is it possible for only part of boost::scoped_ptr's entire definition to exist?

I feel like I'm missing something from your question.
There's only one body (".cpp") file being used in this example, so it goes there. More precisely, it goes into the same object file (".o", ".obj", etc) as that destructor. The language standard doesn't specify this, but that's how all the implementations I'm familiar with do it.

Related

What's the design pattern and advatages of holding a shared_ptr to the implementation within a Class?

Such as:
//Foo.cpp
class Foo{
private:
std::shared_ptr<FooImpl> impl_;
}
//FooImpl.cpp
class FooImpl{
//in this class, major implementations of Foo's details are in here.
}
Above is the example. FooImpl gives the memory allocating, instances variables defining and so on. Foo only holds a private shared_ptr to an instance of the FooImpl.
The design pattern is "The pimpl idiom" (which gets it's name by abbreviating Pointer to Implementation).
The design pattern consists of putting the implementation of a class (the "implementation") in a .cpp file, and leaving in the header file only the definition of an interface/entry point to that class (your "Foo" external class in your example).
Some of the advantages:
the dependencies of the implementation class do not need to be included in the header declaring the Foo class. This can speed up compilation and avoid importing a library you want to avoid having all-over your code base.
the polymorphic character of FooImpl is preserved. Client code only works with the interface of Foo, but you can hide multiple implementations behind it, by specializing FooImpl through inheritance, and instantiating the pointer with a derived class.
The ABI remains stable. In case your FooImpl has an API that is templated (or one that changes very often), making any change to the API of FooImpl would trigger the rebuilding of all the code that includes Foo's header file. This is an operation that (depending on your code base) can take minutes or hours. By hiding the definition of FooImpl inside Foo.cpp, when you modify the API of FooImpl, building the modified code involves only recompiling Foo.cpp and linking everything again.

Why is inheritance not implicitly defined

This may have been answered before, but I couldn't find the words.
I'm trying to wrap my head around inheritance in C++, but coming from C# I can't seem to understand the reasoning behind the following case:
Foo.h
class Foo {
virtual void DoSomething();
}
class Bar : Foo { }
Bar.cpp
#include "Foo.h"
void Bar::DoSomething()
{
//Compiler error C2509 - member function not declared in 'Bar'
}
Since DoSomething is a pure virtual function, wouldn't it stand to reason that it would implicitly be declared as part of Bar?
If I have a lot of different classes inheriting from Foo, do I really need to explicitly declare DoSomething in each one of them?
What other constructs exist in C++ to handle this case?
C++ language is built on the same principles of independent translation as C. This means that all translation units in C++ program should be compilable completely independently of each other. They are linked into the final program later, when the compiler proper has already finished working.
In case of classes, in order to be able to compile each translation unit independently the compiler must be able to build a sufficiently complete understanding of what the given class is by seeing the definition of the class alone, i.e. the part that is usually placed in header files. While compiling one translation unit, the compiler has to know that DoSomething is overriden in Bar and that the definition for void Bar::DoSomething() exists somewhere, in some other translation unit. In order to achieve that the class definition must include declarations for all class member functions.
Your reasoning about "pure virtual function" is completely unclear to me. Firstly, it is not pure in your code sample (apparently you simply forgot the = 0 part). Secondly, just because the base class function is pure does not mean that the derived class function should be non-pure. It is quite possible that Bar was also supposed to be an abstract class. It is matter of your intent, which the compiler does not know.
The definition of Bar is all most code is going to know about it. Other translation units will not see "Bar.cpp" but are still going to need to generate the correct in-memory representation of Bar instances, including Bar's vtable. That means they need to know whether or not Bar is really overriding Foo::DoSomething or not, because the in-memory representation differs depending on that.
Yes, you do need to explicitly declare this method. Coming from C#, you'll notice that C++ does not 'hold your hand' through a lot of things. I don't mean that insultingly, but C++ forces you to be incredibly explicit in everything you do.

Why we need to copy-and-paste functions declaration into inherited class header

This is for C++.
Usually we have our function declaration in header file and definition in source file.
Say we have a class A with some functions:
//< A.hpp
class A
{
public:
virtual funcA();
virtual funcB();
}
And we want to have a class inherit from A and override its functions.
//< childA.hpp
class childA
{
virtual funcA();
virtual funcB();
}
Everytime we change the declarations of funcA() funcB(), we need to copy-and-paste the new declarations to the child classes header files. If the inheritance chain is long, it's quite bother.
I remember we don't have this problem with Object-C, do we?
You don't need to copy a member function declaration to the child class's header file unless you want to override it. In that case, I believe the main reason you're required to declare it is to inform anyone reading your header file that the child class is providing a different implementation. In principle, the compiler can figure it out automatically, but it could be a real pain for a human to do the same thing manually.
Note that in many cases, people reading your header files may not have access to the actual source code for the body (e.g., if it's a proprietary library that is delivered to them as compiled objects), so they can't just go look at the body to figure it out.
From the Objective-C article on Wikipedia:
Objective-C, like Smalltalk, can use dynamic typing: an object can be sent a message that is not specified in its interface.
http://en.wikipedia.org/wiki/Type_system#Dynamic_typing
C++, on the other hand, is statically typed. It's a stricter compile-time restraint.

Can I create functions without defining them in the header file?

Can I create a function inside a class without defining it in the header file of that class?
Why don't you try and see?
[˙ʇ,uɐɔ noʎ 'oᴎ]
Update: Just to reflect on the comments below, with the emphasis of the C++ language on smart compiling, the compiler needs to know the size of the class (thus requiring declaration of all member data) and the class interface (thus requiring all functions and types declaration).
If you want the flexibility of adding functions to the class without the need to change the class header then consider using the pimpl idiom. This will, however, cost you the extra dereference for each call or use of the function or data you added. There are various common reasons for implementing the pimpl:
to reduce compilation time, as this allows you to change the class without changing all the compilation units that depend on it (#include it)
to reduce coupling between a class' dependents and some often-changing implementation details of the class.
as Noah Roberts mentioned below the pimpl can also solve exception safety issues.
No. However, you can mimic such:
struct X
{
void f();
X();
~X();
private:
struct impl;
impl * pimpl;
};
// X.cpp
struct X::impl
{
void f()
{
private_function();
...
}
void private_function() { ...access private variables... }
};
//todo: constructor/destructor...
void X::f() { pimpl->f(); }
Short answer: No, you can't.
However, if you're trying to inject a private function into the class that will only be used in that class's implementation, you can create a function in an anonymous namespace within that class's .cpp file that takes an object of that type by reference or pointer.
Note that you won't be able to muck with the passed objects internal state directly (since there's no way for the class to declare friendship with that anonymous function), but if the function just aggregates operations from the public interface of the class it should work just fine.
No, you can't. It wouldn't make much sense anyway. How should users of your class that include the header file know about those functions and use them?
I have no idea what You are trying to do, but I have a strange gut feeling, that Pointer To Implementation (pImpl) idiom might be helpful. If you want to add a public method in a cpp file and that method is not declared in the class definition in a header, You can't do that and it doesn't make sense.

A few questions about C++ classes

I have two basic questions. The first one is about function in other classes. If I have a header file with a class in it and I want to use that function in another class I have created, do I always have to construct a class object to run a function in that class like:
someclass class; <----object construction
class.somefunction();
Is there a way just to call the function with the object construction?
And the second question is it okay to put multiple small classes in one header file?
Functions should only be member functions if they act on an object of the class. Functions that don't act on an object should just be plain global functions (or class static):
// Global function
void foo() { /* do something */ }
// Static function
class Foo
{
public:
static void foo() { /* do something */ }
};
For your second question, yes it's ok. Generally people stick to one class per file, but in my opinion there's nothing wrong with having a few small classes in a single file.
If your function is declared static then you don't need an object instance to call it.
class Foo
{
public:
static void Bar() {}
};
// ...later
Foo::Bar();
To answer your second question, yes it's sometimes ok. I've done that before with small utility structs that are related to each other. Usually I'm just being lazy and don't want to bother making separate files.
Is there a way just to call the function with the object construction?
Only if the function is declared static. (ok, that's a lie, its possible without constucting a object if you subvert the type system, but it's not a good idea)
And the second question is it okay to put multiple small classes in one header file?
Sure, it's done all of the time.
1 static as already mentioned
2 do what feels natural. Keep related classes together. One of the problems with JAva is its fanatical enforcement of one class per file
However - unforgivable sin is spreading the implementation of class a throughout the implementations of classes b c and d
Ie all of a class implementation should be in one .cpp file.
delcare the function as static.
Are you talking about inner classes? If thats the case, then its totally legit.