C ++模板基本程序,链接器找不到构造函数和析构函数

时间:2010-11-23 12:25:56

标签: c++ templates linker

  

可能重复:
  Why can templates only be implemented in the header file?

您好。我在c ++中有一个愚蠢的程序,它包含一个头文件,其中一个类使用模板,一个cpp文件包含方法实现。

这是标题:

namespace SynQueueing {
  template < class T, unsigned long SIZE = 0 > 
  class CommQueue { 
     public: 
        CommQueue(); 
        ~CommQueue(); 
  }
}

这是cpp

#include "myheader.h"
using namespace SynQueueing;
/* Default constructor */
template < class T, unsigned long SIZE >
CommQueue<T, SIZE>::CommQueue() {
}
/* Default destructor */
template < class T, unsigned long SIZE >
CommQueue<T, SIZE>::~CommQueue() {
}

在主要内容中我只创建一个CommQueue对象

CommQueue cq;

当然在cpp主文件中包含CommQueue.h。

好吧,编译器疯了,告诉我这个:

  

/tmp/ccvJL8VI.o:在函数`main'中:

     

entry.cpp :(。text + 0x2c):未定义的引用`SynQueueing :: CommQueue :: CommQueue()'

     

entry.cpp :(。text + 0x10e):未定义的引用`SynQueueing :: CommQueue :: ~CommQueue()'

     

entry.cpp :(。text + 0x135):未定义引用`SynQueueing :: CommQueue :: ~CommQueue()'

     

collect2:ld返回1退出状态

entry.cpp是main所在的文件。 有什么想法吗?

由于

4 个答案:

答案 0 :(得分:7)

对于模板,您通常必须将实现放在.h / .hpp文件中。这可能看起来不自然,但是将模板视为一些特殊的“宏”,一旦您提供实际类型或值(在您的情况下,类型T和值SIZE),编译器就会扩展。由于大多数编译器都已实现(在您的情况下为GCC),编译器必须在编译时找到要插入的代码,并且它会看到您定义的模板的实例化。

答案 1 :(得分:0)

cpp文件中没有发生模板实例化。

基本上,要解决这个问题,您需要将整个定义放在头文件中,或者在实现或头文件中声明实例化。

e.g。如果您需要CommQueue<int>,请将template class CommQueue<int>;放入实施文件中看到的某个文件中。

答案 2 :(得分:0)

这个想法是模板定义了函数或类型的“族”。这就是为什么你不能简单地在.cpp文件中定义函数并期望将它一次编译为.obj。每次使用新模板参数 T 时,都会创建一个新类型,并且需要编译新函数。

T 的选择无限多,因此模板函数的定义需要在每次实例化时都可供编译器使用,而不仅仅是要链接的某些.obj文件中的编译代码在,与常规功能一样。

答案 3 :(得分:-2)

当您的类被模板化时,您无法在* .cpp文件中定义类主体 当C ++ 0x出现时,将删除此限制。