Created
March 3, 2014 23:30
-
-
Save dwilliamson/9336903 to your computer and use it in GitHub Desktop.
Another minor trick to keep header inclusions down
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Assume a header file with a container of items | |
// Container.h | |
// ------------------------------------------------- | |
#include <vector> | |
// Forward-declared to avoid included header file | |
struct Item; | |
struct Container | |
{ | |
std::vector<Item> items; | |
}; | |
// When included, this works fine | |
// When client tries to use it, a compile error occurs | |
// ------------------------------------------------- | |
#include "Container.h" | |
Container c; // error C2036: 'Item *' : unknown size | |
// Now add a constructor/destructor: | |
// ------------------------------------------------- | |
struct Container | |
{ | |
Container(); | |
~Container(); | |
}; | |
Container c; // unresolved external symbol "public: __thiscall Container::~Container(void)" (??1Container@@QAE@XZ) (...) | |
// The errors shift from the compiler to the linker. When the constructor/destructor are implemented in a private | |
// implementation file (i.e. Container.cpp), everything now works. | |
// They key take-away is that when you don't add your own ctor/dtor the compiler will generate one for you. However, | |
// these will be generated in the compilation unit that includes the header file, thus requiring std::vector to also | |
// generate its ctor/dtor. Of course, std::vector stores Item* internally so the forward-declaration is sufficient until | |
// we realise that the dtor needs to call the Item dtor for each allocated element. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment