web-dev-qa-db-fra.com

C ++: impossible de déclarer le champ comme étant de type abstrait

J'obtiens cette erreur lors de la compilation -> impossible de déclarer le champ M1 :: sc comme étant de type abstrait I1 car les fonctions virtuelles suivantes sont pures dans I1. Veuillez aider.

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

Le code complet peut être trouvé sur http://Pastebin.com/PFrMTJuF .

21
user522767

Les classes abstraites ne peuvent pas être instanciées, mais vous demandez au compilateur de faire exactement cela en incorporant une instance de I1 Dans chaque instance de M1.

Vous pouvez contourner ce problème en modifiant légèrement votre conception et en incorporant un pointeur (ou un pointeur intelligent, si vous pouvez les utiliser) à une instance de I1 À la place:

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

EDIT: Après avoir lu votre code, je pense que le moyen le plus simple et le plus propre de résoudre votre problème est de passer la salle actuelle à la Execute() méthode de votre commande, par exemple quelque chose comme:

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;
    }
}
17
Frédéric Hamidi

I1 est une classe abstraite car elle a des fonctions purement virtuelles (= fonctions sans définition).

Vous ne pouvez pas créer d'instances de classes abstraites (car comment fonctionneraient-elles?!), Donc une déclaration telle que I1 a ne fonctionne pas.

Après avoir modifié la question, il semble que I1 ne doit pas être une classe abstraite, car vous avez fourni des définitions pour les méthodes. Si tel est le cas, supprimez simplement le = 0 après vos déclarations de méthode pour faire fonctionner le code.

7
Konrad Rudolph

Vous ne pouvez pas créer d'instance vers une classe abstraite (la classe qui a une ou plusieurs fonctions virtuelles pures). Il y a aussi un autre problème. Que voulez-vous que le compilateur fasse lorsque vous appelez la fonction sc.a(dir) dans la déclaration de classe? La ligne dir = 4 est également incorrect, seuls les membres const statiques de la classe peuvent être initialisés dans la déclaration de classe.

1
Mihran Hovsepyan