【发布时间】:2012-02-03 21:17:57
【问题描述】:
我不知道为什么会发生这种情况,因为我认为我已经正确声明和定义了所有内容。
我有以下程序,用模板设计。这是一个队列的简单实现,具有成员函数“add”、“substract”和“print”。
我已经在“nodo_colaypila.h”中定义了队列的节点:
#ifndef NODO_COLAYPILA_H
#define NODO_COLAYPILA_H
#include <iostream>
template <class T> class cola;
template <class T> class nodo_colaypila
{
T elem;
nodo_colaypila<T>* sig;
friend class cola<T>;
public:
nodo_colaypila(T, nodo_colaypila<T>*);
};
然后在“nodo_colaypila.cpp”中实现
#include "nodo_colaypila.h"
#include <iostream>
template <class T> nodo_colaypila<T>::nodo_colaypila(T a, nodo_colaypila<T>* siguiente = NULL)
{
elem = a;
sig = siguiente;//ctor
}
接下来是队列模板类及其功能的定义和声明:
“cola.h”:
#ifndef COLA_H
#define COLA_H
#include "nodo_colaypila.h"
template <class T> class cola
{
nodo_colaypila<T>* ult, pri;
public:
cola<T>();
void anade(T&);
T saca();
void print() const;
virtual ~cola();
};
#endif // COLA_H
“cola.cpp”:
#include "cola.h"
#include "nodo_colaypila.h"
#include <iostream>
using namespace std;
template <class T> cola<T>::cola()
{
pri = NULL;
ult = NULL;//ctor
}
template <class T> void cola<T>::anade(T& valor)
{
nodo_colaypila <T> * nuevo;
if (ult)
{
nuevo = new nodo_colaypila<T> (valor);
ult->sig = nuevo;
ult = nuevo;
}
if (!pri)
{
pri = nuevo;
}
}
template <class T> T cola<T>::saca()
{
nodo_colaypila <T> * aux;
T valor;
aux = pri;
if (!aux)
{
return 0;
}
pri = aux->sig;
valor = aux->elem;
delete aux;
if(!pri)
{
ult = NULL;
}
return valor;
}
template <class T> cola<T>::~cola()
{
while(pri)
{
saca();
}//dtor
}
template <class T> void cola<T>::print() const
{
nodo_colaypila <T> * aux;
aux = pri;
while(aux)
{
cout << aux->elem << endl;
aux = aux->sig;
}
}
然后,我有一个程序来测试这些功能,如下所示:
“main.cpp”
#include <iostream>
#include "cola.h"
#include "nodo_colaypila.h"
using namespace std;
int main()
{
float a, b, c;
string d, e, f;
cola<float> flo;
cola<string> str;
a = 3.14;
b = 2.71;
c = 6.02;
flo.anade(a);
flo.anade(b);
flo.anade(c);
flo.print();
cout << endl;
d = "John";
e = "Mark";
f = "Matthew";
str.anade(d);
str.anade(e);
str.anade(f);
cout << endl;
c = flo.saca();
cout << "First In First Out Float: " << c << endl;
cout << endl;
f = str.saca();
cout << "First In First Out String: " << f << endl;
cout << endl;
flo.print();
cout << endl;
str.print();
cout << "Hello world!" << endl;
return 0;
}
但是当我构建时,编译器会在模板类的每个实例中抛出错误:
对 `cola(float)::cola()' 的未定义引用...(实际上是 cola''::cola(),但这不会让我就是这样用的。)
等等。总共有 17 个警告,计算程序中被调用的成员函数的警告。
这是为什么?那些函数和构造函数是被定义的。我认为编译器可以将模板中的“T”替换为“float”、“string”等;这就是使用模板的优势。
我在这里读到,出于某种原因,我应该将每个函数的声明放在头文件中。那正确吗?如果是这样,为什么?
【问题讨论】:
-
您在 nodo_colaypila.h 的末尾缺少
#endif -
也许
nodo_colaypila<T>* ult, pri;应该是nodo_colaypila<T> *ult, *pri;。两者都应该是指针,对吧? -
还有第三个小错误:如果函数的参数有默认值,那么这应该在头文件中定义,而不是在实现中。 (更准确地说,(第一个)声明应该有默认值。)
-
@LightnessRacesinOrbit,经常回答是的。但并不总是完全正确 :-) 有一些方法可以将模板的成员函数的实现保留在一个翻译单元中,同时允许其他翻译单元链接到它们。看我的回答。
-
@LightnessRacesinOrbit:也许回答了一百万次!但是您甚至没有提供单个链接并将其标记为重复...
标签: c++ templates compiler-errors codeblocks