正文

C++为什么不支持类模板的声明与实现的分离?2009-09-28 15:35:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/manbuyuduan/48319.html

分享到:

【转】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要了,有人要自然就得给实例化,这样做的坏处,一个文件可能会被包函多次,出现编译错误。

阅读(3072) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册