2010-12-04 2 views
0

Я пытался найти, что проблема с этой следующей частью кода. Я написал специальный класс исключений, в котором у меня есть базовый класс для ошибок стека, а затем некоторые классы, вытекающие из него, называются stack_full_error. У меня есть проблема с компиляцией, хотя, я получаю следующую ошибку.Ошибка ссылки на символ C++

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++; 
} 

ответ

2

Чистая виртуальная или нет, stack_error должен определить его деструктор, поскольку он неявно вызывается из stack_full_error деструктора. Вы должны добавить:

stack_error::~stack_error() {} 

в файле реализации.

+0

sweet решил проблему, не знал, что вам нужно было определить деструктор, хотя он сделан чистым виртуальным. – starcorn 2010-12-04 15:53:21

1

Вы не можете иметь абстрактный деструктор. Вы должны определить его в stack_error. (см. корректировку ниже)

Возможно, вы имели в виду virtual?

В отличие от других виртуальных функций, виртуальные деструкторы не переопределяют друг друга. Деструкторы всех базовых классов будут выполняться последовательно (начиная с деструктора самого производного класса). Каждый класс должен иметь деструктор; даже если вы не определяете деструктор, он создается неявно.

Исправление:
Вы можете сделать деструктор аннотацию, но нужно определить свое тело в любом случае. Например:

virtual ~stack_error() = 0 {}; 

Если это ваш компилятор, то последние возможности C++ 0x. В противном случае вы должны определить тело снаружи:

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

Аннотация (=0) означает, что она должна быть определяет в производных классах; тем не менее вы должны определить тело деструктора.

+0

Чистые виртуальные функции могут не иметь встроенного определения, и я не уверен, что изменения в C++ 0x – icecrime 2010-12-04 15:33:21

+0

@icecrime: ну, AFAIK в C++ 0x этот синтаксический сахар разрешен. Я проверил с моим текущим компилятором, он все еще не позволяет это :-(. – Vlad 2010-12-04 15:46:01

0

Я не уверен, что деструкторы могут (должны?) Быть абстрактными. Destructors should be virtual, но я, кажется, помню, что у меня были проблемы, когда они были абстрактными.

Смежные вопросы