【转】http://www.pexwin.cn/Topic.aspx?BoardID=2&TopicID=291 C++不支持类模板的声明与实现分离: 普通的实例: \***********THead.h*********\ class TA { int a; public: TA(); } \*********THead.cpp*********\ TA::TA() { } \*********tmain.cpp********\ #include "THead.h" #include <iostream> using namespace std; int main() { TA ta; } \************************\ 分析: 编译main.cpp时,要调用TA的构造函数,但main.cpp没有,所以去"THead.h"找;找到THead.h时也没有找到,所以去所在的目录里找,结果找到了THead.cpp,编译了THead.cpp产生THead.obj,至此已完成了ta的构造. 过程为: 编译:main.cpp生成main.obj,THead.obj 运行连接: 首先加载main.obj,发现没有TA的构造函数模块,于是连接THead.obj找到并继续运行。 模板的实例: \**********Test.h**********\ template<typename T> class A { int a; public: A(); }; \*********Test.cpp********\ template<typename T> A<T>::A() { } \********main.cpp*********\ #include "Test.h" #include <iosteram> using namespace std; int main() { A<int> a; } \************************\ 同理分析: 编译main.cpp时,要调用A<int>的构造函数,但main.cpp没有,所以去"Test.h"找;找到Head.h时也没有 找到,所以去所在的目录里找,结果找到了Test.cpp,(注意这里只是找到,并不是调用),准备编译Test.obj,但是编译器却没有这样做,因为模板的原因,在Test.h并没有使用到A<int>(在Test.h里声明的是A<T>),因为C++规定,只有调用者要用到的时候才会去实例化,而Test.h里全只是声明语句并没有调用A<int>的声明。既然没有需要编译器也不去实例化它了。也就是,main要A<int>,Test.h就把自己的A<T>转化成A<int>但这只是声明,没有定义,这里还要注意Test.h里没有#include "Test.cpp",也就是说Test.h没有告诉Test.cpp.Test.h与Test.cpp并不存在调用的关系。可以是Test.cpp调用Test.h,而不是Test.h调用Test.cpp!!! 过程为: 编译:main.cpp生成main.obj,Test.cpp生成Test.obj 运行连接: 首先加载main.obj,发现没有A<int>的构造函数模块,于是就把这个问题交给了连接器,连接器想找到其它模块连接(Test.obj),可是没有人调用Test.cpp里的模板,也就不会实例化更不会产生关于构造函数的二进制代码。编译无奈宣告无语,显示没有构造函数。报错! 所以解决方案: 把Test.h与Test.cpp合并成一个文件,这样main找Test.h要A<int>时,Test.h就可以实例化,因为自身里有A<int>,有人要就实例化。这样的坏处就是破坏了声明与实现分工。 还有一个就在改为#include "Test.cpp",这样主函数就不用去找Test.h而直接找Test.cpp要了,有人要自然就得给实例化,这样做的坏处,一个文件可能会被包函多次,出现编译错误。

评论