模板类的定义与声明

      写了一个模板类,类似其它类那样把定义与声明分开,结果发现只是引用.h文件根本找不到函数的定义。查看相关资料发现如下解释

  1. 模板是不是一个类或函数。 模板是一个“模式”,编译器用来生成的相似的或者函数
  2. 为了让编译器生成的代码,它必须同时看到模板的定义(不只是声明)和特定类型/任何用于“fill in”模板的类型。例如,如果你想使用一个foo<int>,编译器必须同时看到foo模板和你要调用具体的foo<int>。
  3. 编译器可能不记得另外一个.cpp文件的细节,当编译其他.cpp文件的时候。它可以 ,但大多数都没有,如果你正在阅读本FAQ,它几乎肯定不会。顺便说一句,这就是所谓的“独立编译模型”。

现在,基于这些事实,下面是一个范例,它表明为什么是这个样子。假设你有一个这样的模板Foo声明:

 template<typename T>
 class Foo {
 public:
   Foo();
   void someMethod(T x);
 private:
   T x;
 };

类似地,模板成员函数的定义:

 template<typename T>
 Foo<T>::Foo()
 {
   ...
 }
 
 template<typename T>
 void Foo<T>::someMethod(T x)
 {
   ...
 }

现在,假设在文件Bar.cpp的一些代码要使用foo<int>:

 // Bar.cpp
 
 void blah_blah_blah()
 {
   ...
   Foo<int> f;
   f.someMethod(5);
   ...
 }

显然,某人某地将不得不调用“模式”的构造函数,和someMethod()函数以及做T为int的实例化。但是,如果你把构造函数和someMethod()的定义放到文件Foo.cpp,当编译Foo.cpp时,编译器将看到模板代码;当编译Bar.cpp时,编译器将看到foo<int>。但任何时候决不会同时看到模板代码和foo<int>。因此,通过上面的2号规则,它根本不会产生foo <int>::someMethod()的代码

 

解决方法:

1.把声明跟定义写在一个文件

2,在使用的时候包含.h及cpp

 

例如,考虑foo.h头文件包含以下模板函数声明:

 // File "foo.h"
 template<typename T>
 extern void foo();

现在假设文件foo.cpp实际上定义的模板函数:

 // File "foo.cpp"
 #include <iostream>
 #include "foo.h"
 
 template<typename T>
 void foo()
 {
   std::cout << "Here I am!\n";
 }

假设文件main.cpp中使用这个模板函数通过调用foo<int>():

 // File "main.cpp"
 #include "foo.h"
 
 int main()
 {
   foo<int>();
   ...
 }

如果你编译和(试图)链接这两个.cpp文件,大多数编译器将生成链接错误。有三种的解决方案。第一个解决方案是物理上在.h文件中定义,即使它不是一个内联函数。这种解决办法可能(或可能不会!)造成重大代码膨胀,意味着可执行文件的大小可能会显显著增加(或者,如果你的编译器足够聪明,可能不会这么做)。

另一个解决办法是保留定义在.cpp文件中,只添加行template void foo<int>()到.cpp文件:

 // File "foo.cpp"
 #include <iostream>
 #include "foo.h"
 
 template<typename T> void foo()
 {
   std::cout << "Here I am!\n";
 }
 
 template void foo<int>();

如果你不能修改foo.cpp,只需创建一个新的.cpp文件,例如foo-impl.cpp如下:

 // File "foo-impl.cpp"
 #include "foo.cpp"
 
 template void foo<int>();

请注意, foo-impl.cpp文件包含.cpp文件,而不是.h文件。如果你觉着这样很乱,跳个踢踏舞,想想堪萨斯,跟着我重复,“我要这么做即使它很混乱。” 你需要信任我。如果不信任或者致使好奇,前面的FAQ给出了理由。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值