C ++符号引用错误

时间:2010-12-04 15:07:58

标签: c++ templates inheritance exception-handling

我一直试图找到以下代码部分的问题。我编写了一个自定义异常类,其中我有一个用于堆栈错误的基类,然后是从它派生的一些类,其中一个类称为stack_full_error。 我有一些问题编译它,我得到以下错误。

Undefined                       first referenced
 symbol                             in file
stack_error::~stack_error()         /var/tmp//ccFwZ5Kd.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

它讲述了一些关于析构函数的内容,我一直在尝试修复它,但没有成功。无论如何,我希望有人能告诉我这是什么问题。

class stack_error : public exception
{
public:
   stack_error(string const& m) throw()
      : exception(), msg(m) {};
   virtual ~stack_error() throw() =0;
   virtual const char* what() const throw()
   {
      return msg.c_str();
   }

private:
   string msg;
};

class stack_full_error : public stack_error
{
public:
   stack_full_error() throw()
      : stack_error("Exception: stack full") {};
   ~stack_full_error() throw() {};
};

这是我第一次调用异常的地方

template <class T>
void Stack<T>::push(T i)
{   
   if(is_full())
      throw stack_full_error();

   this->first = new Node<T>(this->first, i);
   amount++;
}

3 个答案:

答案 0 :(得分:2)

纯虚拟与否,stack_error必须定义其析构函数,因为它是从stack_full_error析构函数隐式调用的。你应该添加:

stack_error::~stack_error() {}

在实施文件中。

答案 1 :(得分:1)

你不能有一个抽象的析构函数。您需要在stack_error中定义它。 (见下面的更正)

你的意思是虚拟吗?

与其他虚拟函数不同,虚拟析构函数不会相互覆盖。所有基类的析构函数将按顺序执行(从最派生的类析构函数开始)。每个班级都必须有一个析构函数;即使你没有定义析构函数,它也是隐式创建的。

<强>校正:
你可以使析构函数抽象,但无论如何都需要定义它的主体。像那样:

virtual ~stack_error() = 0 {};

如果这是你的编译器最新的C ++ 0x功能。否则你必须在外面定义身体:

class stack_error
{
    ...
    virtual ~stack_error() = 0;
    ...
};
stack_error::~stack_error() {}

Abstract(=0)意味着它需要在派生类中定义;然而,你必须定义析构函数的主体。

答案 2 :(得分:0)

我不确定析构函数可以(应该?)是抽象的。 Destructors should be virtual但我似乎记得在抽象时遇到问题。