超郁闷中,类模板问题
我想用栈实现简单的计算器功能,用了三个文件,如下:
stak.h文件:
const int maxstack=10; // small value for testing
enum Error_code{success,overflow,underflow};
template <class Stack_entry>
class Stack{
public:
Stack();
bool empty()const;
Error_code pop();
Error_code top(Stack_entry &item)const;
Error_code push(const Stack_entry &item);
private:
int count;
Stack_entry entry[maxstack];
};
文件stack.cpp:
#include "stack.h "
#include <iostream>
template <class Stack_entry>
Stack <Stack_entry> ::Stack()
{
count=0;
}
template <class Stack_entry>
Error_code Stack <Stack_entry> :: push(const Stack_entry &item)
{
Error_code outcome=success;
if(count> =maxstack)
outcome=overflow;
else
entry[count++]=item;
return outcome;
}
template <class Stack_entry>
Error_code Stack <Stack_entry> ::pop()
{
Error_code outcome=success;
if(count==0)
outcome=underflow;
else
--count;
return outcome;
}
template <class Stack_entry>
Error_code Stack <Stack_entry> ::top(Stack_entry &item) const
{
Error_code outcome=success;
if(count==0)
outcome=underflow;
else
item=entry[count-1];
return outcome;
}
template <class Stack_entry>
bool Stack <Stack_entry> ::empty()const
{
bool outcome=true;
if(count> 0)
outcome=false;
return outcome;
}
文件jsqtest.cpp:
#include <iostream>
#include "stack.h "
#include <cstdlib>
#include <cctype>
using namespace std;
char get_command()
{
char command;
bool waiting=true;
cout < < "select command and press <enter> : ";
while(waiting)
{
cin> > command;
command=tolower(command);
if(command== '? ' ||command== '= ' || command == '+ '
||command== '- ' || command == '* ' || command ==
'/ ' || command== 'q ')
waiting=false;
else
{ cout < < "please enter a valid command: " < <endl < <
"[?]push to stack [=]print top " < <endl < <
"[+] [-] [*] [/] are arithmetic operations " < <endl
< < "[q]uit. " < <endl;
}
}
return command;
}
bool do_command(char command,Stack <double> &numbers)
{
double p,q;
switch(command)
{
case '? ':
cout < < "enter a real numeber: " < <flush;
cin> > p;
if(numbers.push(p)==overflow)
cout < < "warning:stack full,lost number " < <endl;
break;
case '= ':
if(numbers.top(p)==underflow)
cout < < "stack empty " < <endl;
else
cout < <p < <endl;
break;
case '+ ':
if(numbers.top(p)==underflow)
cout < < "stadk empty " < <endl;
else{
numbers.pop();
if(numbers.top(q)==underflow)
{ cout < < "stack has just one entry " < <endl;
numbers.push(p);
}
else{
numbers.pop();
if(numbers.push(p+q)==overflow)
cout < < "warning:stack full,lost result " < <endl;
}
}
break;
case 'q ':
cout < < "calculating finishied.\n ";
return false;
}
return true;
}
int main(void)
{ int n;
double item;
Stack <double> store_numbers;
while(do_command(get_command(),store_numbers));
system( "pause ");
return 0;
}
编译通过,但是连接失败,错误代码是: [Linker error] undefined reference to `Stack <double> ::push(double const&) '
[Linker error] undefined reference to `Stack <double> ::top(double&) const '
[Linker error] undefined reference to `Stack <double> ::top(double&) const '
[Linker error] undefined reference to `Stack <double> ::pop() '
[Linker error] undefined reference to `Stack <double> ::top(double&) const '
[Linker error] undefined reference to `Stack <double> ::push(double const&) '
[Linker error] undefined reference to `Stack <double> ::pop() '
[Linker error] undefined reference to `Stack <double> ::push(double const&) '
[Linker error] undefined reference to `Stack <double> ::Stack() '
ld returned 1 exit status
E:\chengxuti\Makefile.win [Build Error] [Stackproject.exe] Error 1
大概是类模板问题,可找不出是哪啊,郁闷啊,各位大侠帮帮忙把
[解决办法]
你直接用stl的stack不就没事了。
[解决办法]
目前的多数编译器 不支持 模版的分离编译。
也就是你得把stack.cpp 的内容拷贝在 stack.h 里面去。
------解决方案--------------------
把 模版的声明和定义 都放在一个 h 文件中,
然后使用 include 这个 h 文件就可以使用了 ~
[解决办法]
又是模板分离式编译的问题
[解决办法]
学习了
[解决办法]
支持分离编译的编译器只有一个商业用的,个人根本搞不到的
[解决办法]
我还没见过支持模板分离编译的编译器
[解决办法]
目前先不要分离编译吧 ...
[解决办法]
C++标准要求编译器实现Template的分离编译,但是目前几乎没有完全实现分离编译的编译器,大部分有这样那样的局限,因为实现的难度很大。
一般类的代码生成(这里是指编译中的代码生成,即生成目标语言)是由定义类的那个编译单元来完成的。如Stack类应由stack.cpp生成目标语言,存在stack.obj文件中,在最后link时加入到可执行文件中。但是对Template而言,必须根据使用情况特化出对应的类。如jsqtest.cpp用到了Stack <double> ,那么需要由一个编译单元生成Stack <double> 的目标代码。但是在各单元独立编译时,stack.cpp不知道要生成Stack <double> ,而jsqtest.cpp因为没有Stack的定义(只有.h中的声明),因而无法生成Stack <double> 。所以在link时,编译器要抱怨没有Stack <double> 各函数的目标代码了。
实现分离编译的一个方法是在link时出现如上的抱怨时,指定stack.cpp重新编译出Stack <double> 。不过结果就是造成linker的复杂化,也降低了编译效率。因此,大部分的编译器没有支持或没有完全支持Template分离编译。
[解决办法]
不过许多编译器提供显示指定特化的功能,用#pragma预编译指令,可以要求stack.cpp编译出Stack <double>