BlaCkOmN
BlaCkOmN

Reputation: 81

C++ issue : Cannot allocate an object of abstract type, but why?

This is some classes of my C++ program.

ElementTerrain.h:

#ifndef ELEMENTTERRAIN_H_
#define ELEMENTTERRAIN_H_

#include <iostream>
#include <string>

using namespace std;

class ElementTerrain {
public:
    virtual ~ElementTerrain(){}
    virtual string getElement() const = 0;
    virtual string getType() const = 0;
    virtual int getStock() const = 0;
};

#endif /* ELEMENTTERRAIN_H_ */

Mine.h:

#ifndef MINE_H_
#define MINE_H_

#include "ElementTerrain.h"

using namespace std;

class Mine : public ElementTerrain{
public:
    Mine();
    Mine(bool, bool, int);
    Mine(const Mine &);
    virtual ~Mine();

    string getElement(){
            return "Mine";
        }

    string getType(){
        if(this->ur == true){
            return "UR";}
        if(this->plu == true){
            return "PLU";}
        return "None";
    }

    int getStock() {
        return stock;
    }

    void setStock(int stock) {
        this->stock = stock;
    }

    bool isUr() {
        return ur;
    }

    bool isPlu() {
        return plu;
    }

private :
    bool ur;
    bool plu;
    int stock;
};

#endif /* MINE_H_ */

Mine.cpp:

#include "Mine.h"

using namespace std;

Mine::Mine() {
    this->ur = false;
    this->plu = false;
    this->stock = 0;
}

Mine::Mine(bool ur, bool plu, int stock){
    this->ur=ur;
    this->plu=plu;
    this->stock = stock;
}

Mine::Mine(const Mine &m){
    this->ur=m.ur;
    this->plu=m.plu;
    this->stock = m.stock;
}

Mine::~Mine() {
    // TODO Auto-generated destructor stub
}

And this is the file where I'm having errors:

#include "ElementRobot.h"
#include "Mine.h"
#include <iostream>

using namespace std;

bool ElementRobot::RecolteMine(Terrain& t, ElementRobot& r) {
    if(t.plateau[x][y]->getElem() != NULL){
            if(t.plateau[x][y]->getElem()->getElement() == "Mine"){
                Mine *m = new Mine();
                if(m.getType() == r.getType() && m.getStock()>0 && r.stock<r.cap){
                    m.setStock(m.getStock()-1);
                    t.plateau[x][y]->setElem((Mine) t.plateau[x][y]->getElem());
                    return true;
                }

                if(m.getType() == r.getType() && m.getStock()==0){
                    cout << "Les stocks de cette mine sont épuisés.\n" << endl;
                }

                if(r.stock==r.cap){
                    cout << "Votre robot ne peut pas porter plus de minerai.\n" << endl;
                }

                if(m.getType() != r.getType()){
                    cout << "Ce robot n'est pas adapté à cette mine.\n" << endl;
                }
            }}
            return false;
}

I want to create an object of type Mine with the copy constructor (here I tried just with the default constructor) but it say that I cannot allocate an object of abstract type Mine, even though in my class Mine there is no pure virtual method. I'm beginner with C++ and I don't understand my mistake. I couldn't find anything on the Internet either.

Upvotes: 2

Views: 4636

Answers (2)

LogicStuff
LogicStuff

Reputation: 19607

The signatures of the Mine's member functions do not match those of the base class (missing const qualifiers). Therefore, you have not overridden, but overloaded them and Mine continues to be abstract and not instantiable.

It's practically like having this:

class Mine {
public:
    // this has to be implemented by deriving classes
    virtual string getElement() const = 0;

    // this is a separate overload
    string getElement() { ... };
};

Solution: Fix the signatures:

string getElement() const { ... }
//                  ^^^^^

and so on...

C++11's override keyword would help you greatly - it would point out that there's no non-const qualified virtual member function named getElement to override.

Upvotes: 9

fnc12
fnc12

Reputation: 2237

You forgot const in function declarations.

Look here:

class ElementTerrain {
public:
    virtual ~ElementTerrain(){}
    virtual string getElement() const = 0;   //  <- notice 'const'
    virtual string getType() const = 0;   //  <- notice 'const'
    virtual int getStock() const = 0;   //  <- notice 'const'
};

So add const keyword to getElement,getType and getStock functions.

class Mine : public ElementTerrain{
public:
    Mine();
    Mine(bool, bool, int);
    Mine(const Mine &);
    virtual ~Mine();

    string getElement() const{    // notice 'const' is added here..
            return "Mine";
        }

    string getType() const{   // notice 'const' is added here..
        if(this->ur == true){
            return "UR";}
        if(this->plu == true){
            return "PLU";}
        return "None";
    }

    int getStock() const{   // notice 'const' is added here..
        return stock;
    }

    void setStock(int stock) {
        this->stock = stock;
    }

    bool isUr() {
        return ur;
    }

    bool isPlu() {
        return plu;
    }

private :
    bool ur;
    bool plu;
    int stock;

};

Also if you want to get rid if this error forever I advice you to add override C++11 keyword after function declaration if you want to override functions like this:

int getStock() const override{
    return stock;
}

In this case your C++ compiler will check if such a virtual function exists in any superclass and will raise a compilation error if it doesn't exist.

Upvotes: 2

Related Questions