I am looking for a simple way to reduce header coupling in a C++ project, which comes mostly due to (overused) class composition which of course requires complete type. For example:
// header A
class A
{
B b; // requires header B
};
I have also considered interfaces and pimpl, but both imply some boilerplate code which I do not want to write/support manually (or is there a way to make this automatic?).
So I thought about replacing member with a pointer and a forward like class B* pB;, but this requires handling of object creation and deletion. Ok, I could use smart pointers for deletion (not auto_ptr though as it requires complete type at creation so say something like shared_ptr<class B> pB;), but how to be with the object creation now?
I could create the object in A's constructor, like pB = new B; but this is, again, manual, and what is worse, there could be several constructors... So I'm looking for a way to do this automatically, which would work as simple as changing B b; to autoobjptr<class B> pB; in A's definition without having to bother with pB instantiation.
I'm pretty sure this is not a new idea, so maybe you could give me a reference to a common solution or a discussion?
UPDATE: To clarify, I am not trying to break the dependency between A and B, but I want to avoid inclusion of B's header when one includes A's one. In practice, B is used in implementation of A, so a typical solution would be to create an interface or pimpl for A but I am looking for something easier for the moment.
UPDATE2: I suddenly realized that a lazy pointer such as proposed here would do the trick (too bad there is no standard implementation of this in say boost), when combined with virtual destructor (to permit incomplete type). I still do not get why there is no standard solution and feel like re-inventing the wheel...
UPDATE3: Suddenly, Sergey Tachenov came with a very simple solution (the accepted answer), though it took me half an hour to understand why it really works...
If you remove A() constructor or define it inline in the header file, the magic won't work anymore (compliation error). I guess that when you define an explicit non-inline constructor, the construction of members (even the implicit ones) is done inside the same compilation unit (A.cpp) where the type B is complete. On the other hand, if your A constructor is inline, creation of the members must happen inside other compilation units and won't work as B is incomplete there. Well, this is logical, but now I'm curious - is this behavior defined by the C++ standard?
UPDATE4: Hopefully, the final update. Refer to the accepted answer and the comments for a discussion on the question above.
At first I got intrigued by this question as it looked like something really tricky to do, and all the comments about templates, dependencies and includes made sense. But then I tried to actually implement this and found it surprisingly easy. So either I misunderstood the question or the question has some special property of looking much harder than it really is. Anyway, here is my code.
This is the glorified autoptr.h:
#ifndef TESTPQ_AUTOPTR_H
#define TESTPQ_AUTOPTR_H
template<class T> class AutoPtr {
private:
T *p;
public:
AutoPtr() {p = new T();}
~AutoPtr() {delete p;}
T *operator->() {return p;}
};
#endif // TESTPQ_AUTOPTR_H
Looks really simple and I wondered if it actually works, so I made a test case for it. Here is my b.h:
#ifndef TESTPQ_B_H
#define TESTPQ_B_H
class B {
public:
B();
~B();
void doSomething();
};
#endif // TESTPQ_B_H
And b.cpp:
#include <stdio.h>
#include "b.h"
B::B()
{
printf("B::B()\n");
}
B::~B()
{
printf("B::~B()\n");
}
void B::doSomething()
{
printf("B does something!\n");
}
Now for the A class that actually uses this. Here's a.h:
#ifndef TESTPQ_A_H
#define TESTPQ_A_H
#include "autoptr.h"
class B;
class A {
private:
AutoPtr<B> b;
public:
A();
~A();
void doB();
};
#endif // TESTPQ_A_H
And a.cpp:
#include <stdio.h>
#include "a.h"
#include "b.h"
A::A()
{
printf("A::A()\n");
}
A::~A()
{
printf("A::~A()\n");
}
void A::doB()
{
b->doSomething();
}
Ok, and finally the main.cpp that uses A, but doesn't include "b.h":
#include "a.h"
int main()
{
A a;
a.doB();
}
Now it actually compiles with no single error nor warning and works:
d:\alqualos\pr\testpq>g++ -c -W -Wall b.cpp
d:\alqualos\pr\testpq>g++ -c -W -Wall a.cpp
d:\alqualos\pr\testpq>g++ -c -W -Wall main.cpp
d:\alqualos\pr\testpq>g++ -o a a.o b.o main.o
d:\alqualos\pr\testpq>a
B::B()
A::A()
B does something!
A::~A()
B::~B()
Does that solve your problem or am I doing something completely different?
EDIT 1: Is it standard or not?
Okay, it seems it was the right thing, but now it leads us to other interesting questions. Here is the result of our discussion in the comments below.
What happens in the example above? The a.h file doesn't need b.h file because it doesn't actually do anything with b, it just declares it, and it knows its size because the pointer in the AutoPtr class is always the same size. The only parts of autoptr.h that need the definition of B are constructor and destructor but they aren't used in a.h so a.h doesn't need to include b.h.
But why exactly a.h doesn't use B's constructor? Aren't B's fields initialized whenever we create an instance of A? If so, the compiler may try to inline this code at every instantiation of A, but then it will fail. In the example above, it looks like the B::B() call is put at the beginning of the compiled constructor A::A() in the a.cpp unit, but does the standard require it?
At first it seems that nothing stops the compiler from inlining fields initialization code whenever an instant is created, so A a; turns into this pseudocode (not real C++ of course):
A a;
a.b->B();
a.A();
Could such compilers exist according to the standard? The answer is no, they couldn't and the standard has nothing to do with it. When the compiler compiles "main.cpp" unit, it has no idea what A::A() constructor does. It could be calling some special constructor for b, so inlining the default one before it would make b initialized twice with different constructors! And the compiler has no way to check for it since the "a.cpp" unit where A::A() is defined is compiled separately.
Okay, now you may think, what if a smart compiler wants to look at B's definition and if there is no other constructor than the default one, then it would put no B::B() call in the A::A() constructor and inline it instead whenever the A::A() is called. Well, that's not going to happen either because the compiler has no way to guarantee that even if B doesn't have any other constructors right now, it won't have any in the future. Suppose we add this to b.h in the B class definition:
B(int b);
Then we put its definition in b.cpp and modify a.cpp accordingly:
A::A():
b(17) // magic number
{
printf("A::A()\n");
}
Now when we recompile a.cpp and b.cpp, it will work as expected even if we don't recompile main.cpp. That's called binary compatibility and the compiler shouldn't break that. But if it inlined the B::B() call, we end up with main.cpp that calls two B constructors. But since adding constructors and non-virtual methods should never break binary compatibility, any reasonable compiler shouldn't be allowed to do that.
The last reason for such compilers to not exist is that it doesn't actually make any sense. Even if the members initialization is inlined, it would just increase the code size and will give absolutely no performance increase since there still would be one method call for A::A() so why not to let this method do all the work in one place?
EDIT 2: Okay, what about inline and auto-generated constructors of A?
Another question that arises is what will happen if we remove A:A() from both a.h and a.cpp? Here's what happens:
d:\alqualos\pr\testpq>g++ -c -W -Wall a.cpp
d:\alqualos\pr\testpq>g++ -c -W -Wall main.cpp
In file included from a.h:4:0,
from main.cpp:1:
autoptr.h: In constructor 'AutoPtr<T>::AutoPtr() [with T = B]':
a.h:8:9: instantiated from here
autoptr.h:8:16: error: invalid use of incomplete type 'struct B'
a.h:6:7: error: forward declaration of 'struct B'
autoptr.h: In destructor 'AutoPtr<T>::~AutoPtr() [with T = B]':
a.h:8:9: instantiated from here
autoptr.h:9:17: warning: possible problem detected in invocation of delete
operator:
autoptr.h:9:17: warning: invalid use of incomplete type 'struct B'
a.h:6:7: warning: forward declaration of 'struct B'
autoptr.h:9:17: note: neither the destructor nor the class-specific operator
delete will be called, even if they are declared when the class is defined.
The only error message that is relevant is "invalid use of incomplete type 'struct B'". Basically it means that main.cpp now needs to include b.h, but why? Because the auto-generated constructor is inlined when we instantiate a in main.cpp. Okay, but does this always have to happen or does it depends on the compiler? The answer is that it can't depend on the compiler. No compiler can make an auto-generated constructor non-inline. The reason for that is that it doesn't know where to put its code. From the programmer's point of view the answer is obvious: the constructor should go in the unit where all other methods of the class are defined, but the compiler doesn't know which unit is that. And besides, class methods could be spread across several units and sometimes it even makes sense (like if a part of the class is auto-generated by some tool).
And of course, if we make A::A() explicitly inline either by using the inline keyword or by putting its definition inside the A class declaration, the same compilation error would occur, possibly a bit less cryptic.
The conclusion
It seems it's perfectly fine to employ the technique described above for auto-instantiated pointers. The only thing I'm not sure of is that AutoPtr<B> b; thing inside a.h will work with any compiler. I mean, we can use a forward-delcared class when declaring pointers and references, but is it always correct to use it as a template instantiation parameter? I think there's nothing wrong with that, but compilers may think otherwise. Googling didn't yield any useful results on it either.
I'm pretty sure this can be implemented in the same way as unique_ptr is implemented. The difference would be that the allocated_unique_ptr constructor would allocate the B object by default.
Note however that if you want automatic construction of the B object, it will be instantiated with the default constructor.
You could write an automatic pimpl_ptr<T> which would automatically new, delete, and copy the contained T.
A problem with your approach is that while you could avoid including the header file for B in this way, it doesn't really reduce dependencies.
A better way to reduce dependencies is by letting B derive from a base class declared in a separate header file, and use a pointer to that base class in A. You'd still need to manually create the correct descendant (B) in A's constructor, of course.
It is also very possible that the dependency between A and B is real and in that case you're improving nothing by artificially avoiding to include B's header file.
Well, you gave the best solution yourself, use pointers, and new them in the constructor... If there are more than one constructor, repeat that code there. You could make a base class which does that for you, but that would only mystify the implementation...
Have you thought about a template in class B? This can also solve your header cross-dependencies, but will ost likely increase your compile time... Which brings us to the reason you are trying to avoid these #includes. Have you measured compile time? Is it troubling? Is this the problem?
UPDATE: example for template way:
// A.h
template<class T>
class A
{
public:
A(): p_t( new T ) {}
virtual ~A() { delete p_t }
private:
T* p_t;
};
Again, this will most likely not increase compile time (B.h will need to be pulled in to create the template instance A<B>), it does hower allow you to remove the includes in the A header and source file.
Related
I came about the same issue as described here
Can't allocate class with forward declared value in std::map member variable
in our codebase.
Hoever I also found other cases where our compiler (MSVC 2017) is able to compile this...
After fiddling around with the code I found that defining the con- & destructor in the cpp allows the files to compile.
In test.h:
#ifndef TEST_H
#define TEST_H
#include <map>
struct Incomplete;
class Test {
std::map<int, Incomplete> member;
public:
Test();
~Test();
int foo() { return 0; }
};
#endif
In test.cpp:
#include "test.h"
struct Incomplete {};
Test::Test() {}
Test::~Test() {}
In main.cpp:
#include "test.h"
int main()
{
Test test;
return test.foo();
}
Why does defining the con- & destructor in the cpp file allow member-std::map-variables to use incomplete types?
This is because declaring the class member does not require Incomplete to be complete, but invoking the std::map destructor does, because it necessarily needs to invoke the Incomplete destructor to destroy the map contents. (Invoking the default std::map constructor could require the type to be complete, depending on the implementation. I'm not sure if the spec puts any requirements on this. I can think of at least one implementation that would not require complete types.)
If you rely on the compiler to generate implicit ctors/dtors for you, that means that the type must be complete when the class definition is encountered, because that's when the compiler is going to implicitly generate the ctor and dtor. It's as though you wrote inline Test::Test() {} inline Test::~Test() {} immediately following the class definition. The dtor is implicitly going to destroy the map, which is going to destroy the map contents by calling ~Incomplete() on any stored values, which we can't do without a definition for Incomplete. And there, the whole thing falls apart and you get an error.
However, if you tell the compiler (by way of the Test ctor/dtor declarations) that you will be implementing them later, then it won't generate them, therefore no std::map ctor/dtor invocation gets compiled at that point.
Then you complete the Incomplete type prior to defining the ctor/dtor yourself, so the Incomplete ctor/dtor invocations can be successfully compiled. If you remove the definition of Incomplete then you will run into the same error.
Note that, as others have said, you can side-step this issue by storing pointers/references to the incomplete type in the map instead. A pointer or reference to an incomplete type is actually itself a complete type. However, this may not be desirable in all cases so I'm hesitant to push that solution without knowing more details about how the map will be used.
Scott Meyer states in Effective C++: Item 30: Understand the ins and outs of inlining that constructors and destructors are often worse candidates for inlining.
Defining functions inside a class definition, requests (not commands) them implicitly to be inline. Depending on the quality of your compiler, the compiler decides whether or not (explicitly or implicitly) defined functions be actually inlined or not.
Taking all these into account, is it a better practice to explicitly define empty/copy/move constructors, copy/move assignment operators and destructors as default (i.e. with the default keyword) inside the body files than inside the header files? After all, default deals purely with implementation as opposed to the dual delete?
Without ever reading "Effective C++: Item 30" I can definitely tell that it makes perfect sense to define empty-looking ctors/dtors inside .cpp:
// MyClass.h:
class MyClass
{
public:
MyClass();
~MyClass();
...
}
// MyClass.cpp:
MyClass::MyClass() = default;
MyClass::~MyClass() = default;
This might look like waste for digital ink, but this is exactly how it has to be done for heavy classes that have large inheritance list or lots of non trivial members.
Why do I think it has to be done like this?
Because if you don't do that, then in every other translation unit where you create or delete MyClass compiler will have to emit inline code for entire class hierarchy to create/delete all members and/or base classes. In giant projects this is usually one of main reasons for builds that takes hours.
To illustrate, compare generated assembly with non-inline ctor/dtor and without. Not that if you have multi-level inheritance with virtual classes then amount of generated code grows very fast. Some call it C++ code bloat.
Basically if you have inline function in your class and you use that function in N different cpp files (or worse in some header files that are used by many other cpp files) then compiler would have to emit that code N times in N different object files, and then at link time merge all these N copies into one version. This rule applies basically to any other function, however, it's not very common to make large function inline in header files (because it's just bad). The issue with constructors, destructors and default assignment operators etc is that they may look like empty or no c++ code at all, while they actually need to perform that same operation recursively for all members and base classes and all of that results in very large amount of generated code.
Another use case of defining a destructor = default inside the body file, is the PImpl idiom in combination with std::unique_ptr.
header file: example.hpp
#include <memory>
// Example::Impl is an incomplete type.
class Example
{
public:
Example();
~Example();
private:
struct Impl;
std::unique_ptr< Impl > impl_ptr;
};
body file: example.cpp
#include "example.hpp"
struct Example::Impl
{
...
};
// Example::Impl is a complete type.
Example::Example()
: impl_ptr(std::make_unique< Impl >())
{}
Example::~Example() = default; // Raw pointer in std::unique_ptr< Impl > points to a complete type so static_assert in its default deleter will not fail.
At the point in the code where std::unique_ptr< Impl > is destroyed, Example::Impl must be a complete type. Therefore, implicitly or explicitly defining Example::~Example in the header file will not compile.
A similar argument applies for the move assignment operator (since the compiler-generated version needs to destroy the original Example::Impl) and for the move constructor (since the compiler-generated version needs to destroy the original Example::Impl in case exceptions).
I ran across this issue in my application after checking it for memory leaks, and discovered that some of my classes are not being destroyed at all.
The code below is split into 3 files, it is supposed to implement a pattern called pimpl. The expected scenario is to have both Cimpl constructor and destructor print their messages. However, that's not what I get with g++. In my application, only constructor got called.
classes.h:
#include <memory>
class Cimpl;
class Cpimpl {
std::auto_ptr<Cimpl> impl;
public:
Cpimpl();
};
classes.cpp:
#include "classes.h"
#include <stdio.h>
class Cimpl {
public:
Cimpl() {
printf("Cimpl::Cimpl()\n");
}
~Cimpl() {
printf("Cimpl::~Cimpl()\n");
}
};
Cpimpl::Cpimpl() {
this->impl.reset(new Cimpl);
}
main.cpp:
#include "classes.h"
int main() {
Cpimpl c;
return 0;
}
Here is what I was able to discover further:
g++ -Wall -c main.cpp
g++ -Wall -c classes.cpp
g++ -Wall main.o classes.o -o app_bug
g++ -Wall classes.o main.o -o app_ok
It looks like the destructor is being called in one of two possible cases, and it depends on the linking order. With app_ok I was able to get the correct scenario, while app_bug behaved exactly like my application.
Is there any bit of wisdom I am missing in this situation?
Thanks for any suggestion in advance!
The goal of the pimpl idiom is to not have to expose a definition of the implementation class in the header file. But all the standard smart pointers require a definition of their template parameter to be visible at the point of declaration in order to work correctly.
That means this is one of the rare occasions where you actually want to use new, delete, and a bare pointer. (If I'm wrong about this and there's a standard smart pointer that can be used for pimpl, someone please let me know.)
classes.h
struct Cimpl;
struct Cpimpl
{
Cpimpl();
~Cpimpl();
// other public methods here
private:
Cimpl *ptr;
// Cpimpl must be uncopyable or else make these copy the Cimpl
Cpimpl(const Cpimpl&);
Cpimpl& operator=(const Cpimpl&);
};
classes.cpp
#include <stdio.h>
struct Cimpl
{
Cimpl()
{
puts("Cimpl::Cimpl()");
}
~Cimpl()
{
puts("Cimpl::~Cimpl()");
}
// etc
};
Cpimpl::Cpimpl() : ptr(new Cimpl) {}
Cpimpl::~Cpimpl() { delete ptr; }
// etc
The problem is that at the point of the definition of the auto_ptr<Cimpl> object, Cimpl is an incomplete type, that is, the compiler has only seen a forward declaration of Cimpl. That's okay, but since it eventually deletes the object that it holds a pointer to, you have to comply with this requirement, from [expr.delete]/5:
If the object being deleted has incomplete class type at the point of
deletion and the complete class has a non-trivial destructor or a
deallocation function, the behavior is undefined.
So this code runs into undefined behavior, and all bets are off.
The code violates the One Definition Rule. There's a definition of the class Cimpl in classes.h, and a different definition of the class Cimpl in the file classes.cpp. The result is undefined behavior. It's okay to have more than one definition of a class, but they must be the same.
Edited for clarity, original retained below.
This code has undefined behavior because in the context of main.cpp the implicit Cpimpl::~Cpimpl destructor only has a forward declaration of Cimpl, but the auto_ptr (or any other form of doing delete) needs a full definition to legally clean up the Cimpl. Given that it's undefined behavior no further explanation for your observations is needed.
Original answer:
I suspect that what's happening here is that the implicit destructor of Cpimpl is being generated in the context of classes.h and not having access to the full definition of Cimpl. Then when the auto_ptr tries to do its thing and clean up its contained pointer, it deletes an incomplete class, which is undefined behavior. Given that it's undefined we don't have to go any further to explain that it's perfectly acceptable for it to work in different ways depending on the link order.
I suspect that an explicit destructor for Cpimpl with a definition in a source file would solve your problem.
EDIT: Actually now that I look at it again, I believe your program violates the one definition rule as it stands. In main.cpp it sees an implicit destructor that doesn't know how to call a destructor of Cimpl (because it only has a forward declaration). In classes.cpp the implicit destructor does have access to Cimpl's definition and thus how to call its destructor.
I'm trying to create a C++ class, with a templated superclass. The idea being, I can easily create lots of similar subclasses from a number of superclasses which have similar characteristics.
I have distilled the problematic code as follows:
template_test.h:
template<class BaseClass>
class Templated : public BaseClass
{
public:
Templated(int a);
virtual int Foo();
};
class Base
{
protected:
Base(int a);
public:
virtual int Foo() = 0;
protected:
int b;
};
template_test.cpp:
#include "template_test.h"
Base::Base(int a)
: b(a+1)
{
}
template<class BaseClass>
Templated<BaseClass>::Templated(int a)
: BaseClass(a)
{
}
template<class BaseClass>
int Templated<BaseClass>::Foo()
{
return this->b;
}
main.cpp:
#include "template_test.h"
int main()
{
Templated<Base> test(1);
return test.Foo();
}
When I build the code, I get linker errors, saying that the symbols Templated<Base>::Templated(int) and Templated<Base>::Foo() cannot be found.
A quick Google suggests that adding the following to main.cpp will solve the problem:
template<> Templated<Base>::Templated(int a);
template<> int Templated<Base>::Foo();
But this does not solve the problem. Adding the lines to main.cpp does not work either. (Though, interestingly, adding them to both gives 'multiply defined symbol' errors from the linker, so they must be doing something...)
However, putting all the code in one source file does solve the problem. While this would be ok for the noddy example above, the real application I'm looking at would become unmanageable very fast if I was forced to put the whole lot in one cpp file.
Does anyone know if what I'm doing is even possible? (How) can I solve my linker errors?
I would assume that I could make all the methods in class Templated inline and this would work, but this doesn't seem ideal either.
With templated classes, the definitions must be available for each translation unit that uses it. The definitions can go in a separate file, usually with .inl or .tcc extension; the header file #includes that file at the bottom. Thus, even though it's in a separate file, it's still #included for each translation unit; it cannot be standalone.
So, for your example, rename template_test.cpp to template_test.inl (or template_test.tcc, or whatever), then have #include "template_test.inl" (or whatever) at the bottom of template_test.h, just before the #endif of the include guard.
Hope this helps!
The problem is that when your Templated file is compiled, the compiler doesn't know what types it will need to generate code for, so it doesn't.
Then when you link, main.cpp says it needs those functions, but they were never compiled into object files, so the linker can't find them.
The other answers show ways to solve this problem in a portable way, in essence putting the definitions of the templated member functions in a place that is visible from where you instantiate instances of that class -- either through explicit instantiation, or putting the implementations in a file that is #included from main.cpp.
You may also want to read your compiler's documentation to see how they recommends setting things up. I know the IBM XLC compiler has some different settings and options for how to set these up.
The C++ FAQ-lite covers this, and a couple of ways round it.
You don't have to make all the methods "inline", but you should define the method bodies in template_test.h, rather in template_test.cpp.
Some compilers can handle this split, but you have to remember that at one level, templates are like macros. for the compiler to generate the a template for your particular , it needs to have the template source handy.
When the compiler is compiling main.cpp, it sees the class definition has member function declarations, but no member function defintions. It just assumes that there must be a definition of "Templated" constructor and Foo implementation somewhere, so it defers to the linker to find it at link time.
The solution to your problem is to put the implementation of Templated into template.h.
eg
template<class BaseClass>
class Templated : public BaseClass
{
public:
Templated(int a) : BaseClass(a) {}
virtual int Foo() { return BaseClass::b; }
};
Interestingly, I could get your code to link by putting this at the end of template_test.cpp.
void Nobody_Ever_Calls_This()
{
Templated<Base> dummy(1);
}
Now the compiler can find an instance of Templated to link with. I wouldn't recommend this as a technique. Some other file might want to create a
Templated<Widget>
and then you'd have to add another explicit instantiation to template_test.cpp.
If I create a class like so:
// B.h
#ifndef _B_H_
#define _B_H_
class B
{
private:
int x;
int y;
};
#endif // _B_H_
and use it like this:
// main.cpp
#include <iostream>
#include <vector>
class B; // Forward declaration.
class A
{
public:
A() {
std::cout << v.size() << std::endl;
}
private:
std::vector<B> v;
};
int main()
{
A a;
}
The compiler fails when compiling main.cpp. Now the solution I know is to #include "B.h", but I'm curious as to why it fails. Neither g++ or cl's error messages were very enlightening in this matter.
In fact your example would build if A's constructor were implemented in a compile unit that knows the type of B.
An std::vector instance has a fixed size, no matter what T is, since it contains, as others said before, only a pointer to T. But the vector's constructor depends on the concrete type. Your example doesn't compile because A() tries to call the vector's ctor, which can't be generated without knowing B. Here's what would work:
A's declaration:
// A.h
#include <vector>
class B; // Forward declaration.
class A
{
public:
A(); // only declare, don't implement here
private:
std::vector<B> v;
};
A's implementation:
// A.cpp
#include "A.h"
#include "B.h"
A::A() // this implicitly calls vector<B>'s constructor
{
std::cout << v.size() << std::endl;
}
Now a user of A needs to know only A, not B:
// main.cpp
#include "A.h"
int main()
{
A a; // compiles OK
}
The compiler needs to know how big "B" is before it can generate the appropriate layout information. If instead, you said std::vector<B*>, then the compiler wouldn't need to know how big B is because it knows how big a pointer is.
To instantiate A::v, the compiler needs to know the concrete type of B.
If you're trying to minimize the amount of #included baggage to improve compile times, there are two things you can do, which are really variations of each other:
Use a pointer to B
Use a lightweight proxy to B
It's more than just the size of B that's needed. Modern compilers will have fancy tricks to speed up vector copies using memcpy where possible, for instance. This is commonly achieved by partially specializing on the POD-ness of the element type. You can't tell if B is a POD from a forward declaration.
Just like fyzix said, the reason your forward declaration is not working is because of your inline constructor. Even an empty constructor might contain lots of code, like the construction of non-POD members. In your case, you have a vector to initialize, which you can't do without defining its template type completely.
The same goes for destructors. The vector needs the template type definition to tell what destructor to call when destroying the instances it holds.
To get rid of this problem, just don't inline constructors and destructors. Define them separately somewhere after B is completely defined.
For more information,
http://www.chromium.org/developers/coding-style/cpp-dos-and-donts
This doesn't matter whether you use a vector or just try to instantiate one B. Instantiation requires the full definition of an object.
Man, you're instancing std::vector with an incomplete type. Don't touch the forward declaration, just move the constructor's definition to the .cpp file.
The reason you can't use a forward declaration is because the size of B is unknown.
There's no reason in your example that you can't include B.h inside of A.h, so what problem are you really trying to solve?
Edit: There's another way to solve this problem, too: stop using C/C++! It's so 1970s... ;)