C ++模板类问题

时间:2011-07-03 20:23:21

标签: c++ templates linker-errors

大家好我只是想练习一些c ++模板,但我得到了链接器错误。有人能帮帮我吗? 这是我的代码:

// File: MyClass.h
#ifndef _MYCLASS_H
#define _MYCLASS_H
template<class T> class MyClass {
T value;
public:
MyClass(T v);
~MyClass();
};
#endif // _MYCLASS_H

// File: MyClass.cpp
#include "MyClass.h"
template<class T> MyClass<T>::MyClass(T v) {
value = v;
}
template<class T> MyClass<T>::~MyClass() {

}

// File: main.cpp
#include "MyClass.h"
int main() {
MyClass<int> test(10);
return 0;
}

这是命令行输出:

g++ main.cpp -c
g++ MyClass.cpp -c
g++ main.o MyClass.o -o Out
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `MyClass<int>::MyClass(int)'
main.cpp:(.text+0x2b): undefined reference to `MyClass<int>::~MyClass()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

正如您所看到的,我正在使用Ubuntu 10.04和GNU C ++编译器。 我在这段代码中遗漏了什么吗?


感谢您的回复。它有效,但没有更好的方法来保护代码? 例如,如果我想创建一个非开源库怎么办?! 我想将代码导出到静态库。并将图书馆链接到其他项目...

4 个答案:

答案 0 :(得分:5)

您必须将完整模板放入标题中。编译器需要在模板实例化的站点上查看模板方法的主体 - 在您的情况下为main.cpp。例如,请参阅C++ FAQ

答案 1 :(得分:1)

您应该将模板类和内联方法放入头文件中。你不能在他们的案例中分离定义和实现。

答案 2 :(得分:1)

@Nikolai N Fetissov拥有正确的解决方案。我想补充一点,这是一个很好的方法,如果你想保持实现和模板化函数定义分开,你可以将实现放入MyClass.hxx并将其包含在您的MyClass.h

结束
// File: MyClass.h 
#ifndef _MYCLASS_H 
#define _MYCLASS_H 

template<class T> class MyClass 
{ 
  T value; 
public: 
  MyClass(T v);
  ~MyClass(); 
}; 

#include "MyClass.hxx"   /// <--- like this
#endif // _MYCLASS_H 

答案 3 :(得分:0)

记住模板是很重要的。它是一个用于生成代码的模板(如果需要);它不是代码本身。

因此,声明模板类并为这些方法编写实现不会为该类生成任何对象代码;它只是提供了一个模板,以便在必要时这样做。

当使用实际参数实例化模板类时,编译器将从模板类生成代码。为此,它需要能够看到模板。但由于您只有#include .h文件,以及.cpp文件中方法的实现,编译器将无法为函数实现生成目标代码。然后,当链接器查找这些定义时,它将找不到它。

所有这些都是一种啰嗦的方式来获得与其他答案相同的结果 - 您需要将实现放在带有类声明的头文件中。但这可能有助于了解其原因。