我正在从我写的一个类中得到一些非常奇怪的链接错误.我完全无法找到任何可以描述正在发生的事情的东西.
Visual Studio(Windows XP)
players.obj:错误LNK2019:未解析的外部符号"public:__thiscall TreeNode :: TreeNode(void)"(?? 0?$ TreeNode @ VPlayer @@@@ QAE @ XZ)在函数"public:__thiscall PlayerList :: PlayerList"中引用(void)"(?? 0PlayerList @@ QAE @ XZ)
Xcode(OSX 10.5)
未定义的符号:"TreeNode ::〜TreeNode()",引用于:player.o中的PlayerList :: ~PlayerList()
头文件:generics.h
class TreeNode : public BaseNode{ public: const static int MAX_SIZE = -1; //-1 means any size allowed. const static int MIN_SIZE = 0; //getters int size() const; vectorgetChildren() const; //setters void setChildren(vector &list); //Serialization virtual void display(ostream &out) const; virtual void read(istream &in); virtual void write(ostream &out) const; //Overrides so SC acts like an array of sorts. virtual C* get(int id) const; virtual int get(C *child) const; virtual bool has(C *child) const; virtual C* pop(int id); virtual void push(C *child); virtual TreeNode& operator<< (C *child); //append virtual void remove(int id); //Clears memory virtual void remove(C *child); //Clears memory //Initalizers TreeNode(); TreeNode(istream &in); TreeNode(long id, istream &in); TreeNode(BaseNode* parent, istream &in); TreeNode(long id, BaseNode* parent); TreeNode(long id, BaseNode* parent, istream &in); ~TreeNode(); string __name__() const{ return "TreeNode"; } protected: void clearChildren(); void initalizeChildren(); vector _children; };
来自TreeNode的子类的代码
PlayerList::PlayerList() : TreeNode(){} PlayerList::PlayerList(istream &in) : TreeNode (in){} PlayerList::~PlayerList(){}
Johannes Sch.. 14
在.cpp文件中定义模板时,必须使用已知的模板将事先使用所有类型/模板参数显式实例化它(将其放在.cpp文件中):
template class TreeNode;
如果您不知道将使用哪个模板参数,则必须将所有定义放入标题中.喜欢
templateclass TreeNode { public: TreeNode() /* now, also put the code into here: */ { doSomething(); } };
原因是当您要从某个地方使用模板时,编译器必须能够为模板的特定实例化生成代码.但是如果将代码放入.cpp文件并进行编译,则编译器无法获取代码来生成实例化(除非使用臭名昭着的export
关键字,只有极少数编译器支持) .
这也是我的C++陷阱答案中的一个条目:我应该避免哪些C++陷阱?
在.cpp文件中定义模板时,必须使用已知的模板将事先使用所有类型/模板参数显式实例化它(将其放在.cpp文件中):
template class TreeNode;
如果您不知道将使用哪个模板参数,则必须将所有定义放入标题中.喜欢
templateclass TreeNode { public: TreeNode() /* now, also put the code into here: */ { doSomething(); } };
原因是当您要从某个地方使用模板时,编译器必须能够为模板的特定实例化生成代码.但是如果将代码放入.cpp文件并进行编译,则编译器无法获取代码来生成实例化(除非使用臭名昭着的export
关键字,只有极少数编译器支持) .
这也是我的C++陷阱答案中的一个条目:我应该避免哪些C++陷阱?