michaeluskov
michaeluskov

Reputation: 1828

'Undefined reference to ' error in GCC Eclipse

I use Eclipse+GCC+MinGW.

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

I get undefined reference to AbstractValue::~AbstractValue() on IntegerValue::~IntegerValue() {}. Why?

Upvotes: 2

Views: 145

Answers (3)

P0W
P0W

Reputation: 47794

Any derived class' destructor ( ~IntegerValue()) must call the base class' destructor (~AbstractValue()), and so the destructor must still be defined (even if it's empty):

So,

// In file AbstractValue.cpp

AbstractValue::~AbstractValue(){ }

Upvotes: 0

user2428400
user2428400

Reputation:

Because

virtual ~AbstractValue() = 0;

Means pure virtual, with no implementation. This is wrong, destructors cannot be pure virtual with no implementation. Use this:

virtual ~AbstractValue() {}

i.e. an empty implementation.

(Side note: a destructor can be pure virtual WITH an implementation, but there is no reason to do this here)

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258608

Pure virtual destructors must have an implementation (as opposed to pure virtual methods, which can be left un-implemented).

Upvotes: 1

Related Questions