2010-11-23 164 views
0

可能重复:
Why can templates only be implemented in the header file?C++模板基本程序,链接器找不到构造函数和析构函数

你好。我在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:在函数'主:

entry.cpp :(文字+ 0x2c上):未定义参考`SynQueueing :: CommQueue :: CommQueue() '

entry.cpp :(文本+ 0x10e):未定义参考`SynQueueing :: CommQueue ::〜CommQueue()'

entry.cpp :(.text + 0x135):对'SynQueueing :: CommQueue ::〜CommQueu的未定义引用E()”

collect2:LD返回1个退出状态

entry.cpp是其中主所在的文件。 有什么想法?

感谢

+0

请参阅:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15 – icecrime 2010-11-23 12:29:22

+0

除了template-in-header问题之外,您是否还需要提供模板参数到实例化?例如`CommQueue cq;` – 2010-11-23 12:34:21

回答

7

对于你平时必须把实现的.H/.HPP文件模板。这可能看起来不自然,但将模板看作是一些给出实际类型或值(在您的案例中,类型为T,值为SIZE)时编译器扩展的特殊“宏”。由于大多数编译器都是实现的(在你的情况下是GCC),编译器必须在编译时找到要插入的代码,并且它看到了你定义的模板的实例化。

+0

好的,谢谢,工作,我保持.h和.cpp分开,并包括在主...可以吗? – Andry 2010-11-23 12:32:11

-2

当你的类被模板化时,你不能在* .cpp文件中定义类体。
当C++ 0x出来时,此限制将被删除。

0

模板实例化不在cpp文件中发生。

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

例如如果您需要CommQueue<int>,则将template class CommQueue<int>;放入实现文件看到的某个文件中。

0

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

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