Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : Cannot declare field to be of abstract type

I get this error on compile -> cannot declare field M1::sc to be of abstract type I1 because the following virtual functions are pure within I1. Please help.

   class I1
    {    
    public:  
        virtual void a(int dir) = 0;
        virtual void b() = 0; 
        virtual void c() = 0; 

        void a(int dir) {  
        ....
        }

        void b() {  
        ....
        }

        void c() {  
        ....
        }
    };

    class I2 : public I1
    {    
    public:  


        void a(int dir) {  
        ....
        }

        void b() {  
        ....
        }

        void c() {  
        ....
        }
    }; 

    class M1 : public G1
    {
    protected:
    I1 sc;
    public:
       int dir = 4;
       sc.a(dir);
    };

Complete code can be found on http://pastebin.com/PFrMTJuF.

like image 580
user522767 Avatar asked Nov 28 '10 10:11

user522767


3 Answers

Abstract classes can't be instantiated, but you're asking the compiler to do just that by embedding an instance of I1 into every instance of M1.

You can work around that by slightly changing your design and embedding a pointer (or a smart pointer, if you can use those) to an instance of I1 instead:

class M1 : public G1
{
protected:
    I1 *sc;
public:
    M1(I1 *sc_) {
        sc = sc_;
    }
    void foo() {
        int dir = 4;
        sc->a(dir);
    }
};

EDIT: After reading your code, I think that the simplest and cleanest way to solve your problem is to pass the current room to the Execute() method of your command, e.g. something like:

class ICommand
{
public:
    virtual ~ICommand()
    {
    }

    virtual void Execute(Room *room) = 0;
};


class MoveCommand : public GameCommand
{
public:
    MoveCommand()
    {
    }

    void Execute(Room *room)
    {
        // Do something with `room`...
    }
};


void Game::HandleInput()
{
    // Read command from user and generate a command object from it.
    ICommand *pCommand = ParseCommand(Input::ReadCommand());
    if (pCommand) {
        pCommand->Execute(GetCurrentRoom());  // Pass current room to command.
        delete pCommand;
    }
}
like image 140
Frédéric Hamidi Avatar answered Oct 21 '22 02:10

Frédéric Hamidi


I1 is an abstract class because it has purely virtual functions (= functions without a definition).

You cannot create instances of abstract classes (because how would they work?!), therefore a declaration such as I1 a doesn’t work.

After your edit to the question it seems as though I1 shouldn’t be an abstract class, since you provided definitions for the methods. If that’s the case, just remove the = 0 after your method declarations to make the code work.

like image 29
Konrad Rudolph Avatar answered Oct 21 '22 04:10

Konrad Rudolph


You can't create instance to abstract class (the class which has one or more pure virtual functions). Also there is another problem. What do you want compiler to do when you call function sc.a(dir) in class declaration? The line dir = 4 is also incorrect, only static const members of class can be initializated in class declaretion.

like image 1
Mihran Hovsepyan Avatar answered Oct 21 '22 04:10

Mihran Hovsepyan