2013-12-15 3 views
2

Я использую Eclipse + GCC + MinGW.«Неопределенная ссылка на ошибку» в GCC Eclipse

AbstractValue.h:

#ifndef ABSTRACTVALUE_H_ 
#define ABSTRACTVALUE_H_ 

#include <string> 


class AbstractValue { 
public: 
    virtual AbstractValue* add(AbstractValue*) = 0; 
    virtual AbstractValue* sub (AbstractValue*) = 0; 
    virtual AbstractValue* mul (AbstractValue*) = 0; 
    virtual AbstractValue* div (AbstractValue*) = 0; 
    virtual std::string toString() = 0; 
    virtual ~AbstractValue() = 0; 
}; 


#endif /* ABSTRACTVALUE_H_ */ 

IntegerValue.h

#ifndef INTEGERVALUE_H_ 
#define INTEGERVALUE_H_ 

#include "../AbstractValue/AbstractValue.h" 
#include <string> 

class IntegerValue: public AbstractValue { 
private: 
    int value; 
public: 
    IntegerValue(int); 
    ~IntegerValue(); 
    int getValue(); 
    IntegerValue* add (AbstractValue*); 
    IntegerValue* sub (AbstractValue*); 
    IntegerValue* mul (AbstractValue*); 
    IntegerValue* div (AbstractValue*); 
    std::string toString(); 
}; 

IntegerValue.cpp:

#include "IntegerValue.h" 
#include <stdlib.h> 

IntegerValue::IntegerValue(int a) : value(a) {}; 

IntegerValue::~IntegerValue() {} 


int IntegerValue::getValue() { 
    return this -> value; 
} 

IntegerValue* IntegerValue::add (AbstractValue* another) { 
    IntegerValue* anotherInteger = (IntegerValue*) another; 
    int newValue = this -> getValue() + anotherInteger -> getValue(); 
    return new IntegerValue(newValue); 
} 

IntegerValue* IntegerValue::sub (AbstractValue* another) { 
    IntegerValue* anotherInteger = (IntegerValue*) another; 
    int newValue = this -> getValue() - anotherInteger -> getValue(); 
    return new IntegerValue(newValue); 
} 

IntegerValue* IntegerValue::mul (AbstractValue* another) { 
    IntegerValue* anotherInteger = (IntegerValue*) another; 
    int newValue = this -> getValue() * anotherInteger -> getValue(); 
    return new IntegerValue(newValue); 
} 

IntegerValue* IntegerValue::div (AbstractValue* another) { 
    IntegerValue* anotherInteger = (IntegerValue*) another; 
    int newValue = this -> getValue()/anotherInteger -> getValue(); 
    return new IntegerValue(newValue); 
} 

std::string IntegerValue::toString() { 
    char *res = new char[1000]; 
    itoa(this -> value, res, 10); 
    std::string a (res); 
    delete[] res; 
    return a; 
} 

Я GE t undefined reference to AbstractValue::~AbstractValue() на IntegerValue::~IntegerValue() {}. Зачем?

ответ

1

Поскольку

virtual ~AbstractValue() = 0; 

Средства чисто виртуальные, без реализации. Это неправильно, деструкторы не могут быть чистыми виртуальными без реализации. Используйте это:

virtual ~AbstractValue() {} 

т. Е. Пустая реализация.

(Примечание стороны: деструктор может быть чисто виртуальный с реализацией, но нет никаких причин, чтобы сделать это здесь)

+0

Да, это работает. Благодаря! – michaeluskov

+0

Вы можете легко это сделать. Кроме того, чистый деструктор заставляет расширяющие классы писать свои собственные и допускать удаление производного объекта с помощью указателя на базовый класс, поэтому он вовсе не бесполезен. –

+0

@ LuchianGrigore Я никогда не видел этого, по крайней мере, не там, где реализация предоставляется производным классом, но я могу представить, как это может быть полезно, настроить обработку частного ресурса для базы в зависимости от реализации производного класса , – polkadotcadaver

1

Pure virtual деструкторы должны иметь реализацию (в отличие от чистых методов virtual, которые могут быть оставлены без изменений).

0

Любой производный класс деструктор (~IntegerValue()) должен вызвать базовый класс деструктор (~AbstractValue()) и поэтому деструктор должен еще быть определен (даже если он пуст):

так,

// In file AbstractValue.cpp 

AbstractValue::~AbstractValue(){ } 
Смежные вопросы