ERROR CODE:
CList<CString,const char*> test;
ERROR INFO:
ECLIPSE / UBUNTU 10
/home/latyas/workspace/CList/Debug/../test.cpp:7: undefined reference
to `CList<CString, char const*>::CList()'
我已经定义了这个构造函数:
template<typename T1, typename T2> CList<T1, T2>::CList() :
m_nHead(0), m_nTail(0),m_nCount(0) {
}
为什么我收到此错误?
更新
#include <iostream>
#include "CString.h"
#include "CList.h"
int main()
{
CList<CString,const char*> test;
test.AddHead("test");
return 0;
}
/*
* CList.h
*
* Created on: 2012-3-31
* Author: latyas
*/
#ifndef CLIST_H_
#define CLIST_H_
template<typename T1,typename T2> class CList {
public:
struct CNode {
CNode* pNext;
CNode* pPrev;
T1 data;
};
CList();
~CList();
long GetHead();
long GetTail();
long GetNext(long, T1&);
long GetCount();
long AddHead(T2);
long AddTail(T2);
long RemoveAt(long);
private:
CNode* m_nHead;
CNode* m_nTail;
long m_nCount;
};
#endif /* CLIST_H_ */
/*
* CList.cpp
*
* Created on: 2012-3-31
* Author: latyas
*/
#include "CList.h"
#include <cstdlib>
#include <iostream>
/
template<typename T1, typename T2> CList<T1, T2>::CList() :
m_nHead(0), m_nTail(0),m_nCount(0) {
}
template<class T1, class T2> CList<T1, T2>::~CList() {
std::cout << "~CList()";
答案 0 :(得分:1)
你没有说你在哪里定义它。我猜你是在一些实现文件中这样做的。但是对于模板,实现必须进入头文件(除非您为它们可能用于的每种类型显式实例化它们)。
为此,将模板视为一种类型安全的宏是有帮助的(但请注意,模板比宏复杂得多,所以请不要过度夸大这种类比)。就像宏一样,模板包含有关如何创建代码的说明;它处于不同的级别(文本级别的宏,语法级别的模板),但基本原理是相同的:模板不是代码,它生成代码。您从未实例化的模板将不会显示在已编译的代码中。
在您定义变量test
的位置,您实例化类型CTest
和CString
的模板const char*
。也就是说,您指示编译器从CList<CString, const char*>
模板生成具体的类CList
。但是由于在那个地方,编译器无法看到析构函数的定义,因此无法生成它。但是它没有抱怨,因为它不知道你没有在其他地方为这些类型实例化它。但是它会生成对它的引用,以便在执行时调用它。
在实现文件中,编译器 看到你的构造函数模板,但你没有在那里实例化它,因此编译器不会从中生成任何代码(它不能这样做)无论如何,因为它不知道你可以在其他地方实例化类的哪种类型。)
现在在链接时,链接器会看到对构造函数CList<CString, const char*>::CList()
的引用(来自您定义test
的文件),但没有定义(因为没有生成)。因此它抱怨缺少参考。
答案 1 :(得分:0)
“未定义的引用”很可能是链接器错误,即链接器找不到源代码引用的库。
您正在使用CString
。它来自哪个图书馆?该库是否为链接器所知?
答案 2 :(得分:0)
模板化类没有.cpp文件,因此所有实现都必须仅在.h文件中完成..
/*
* CList.h
*/
#ifndef CLIST_H_
#define CLIST_H_
template<typename T1,typename T2> class CList {
public:
struct CNode {
CNode* pNext;
CNode* pPrev;
T1 data;
};
CList();
~CList();
long GetHead();
long GetTail();
long GetNext(long, T1&);
long GetCount();
long AddHead(T2);
long AddTail(T2);
long RemoveAt(long);
private:
CNode* m_nHead;
CNode* m_nTail;
long m_nCount;
};
#endif /* CLIST_H_ */
/* ========== Implementation of Clist class ============ */
template<typename T1, typename T2> CList<T1, T2>::CList() :
m_nHead(0), m_nTail(0),m_nCount(0) {
}
template<class T1, class T2> CList<T1, T2>::~CList() {
std::cout << "~CList()";