2010-11-28 17 views
16

Recibo este error en la compilación -> no puedo declarar que el campo M1 :: sc es del tipo abstracto I1 porque las siguientes funciones virtuales son puras dentro de I1. Por favor ayuda.C++: No se puede declarar que el campo sea de tipo abstracto

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

El código completo se puede encontrar en http://pastebin.com/PFrMTJuF.

Respuesta

13

Abstract classes no se puede crear una instancia, pero le está pidiendo al compilador que haga exactamente eso al incrustar una instancia de I1 en cada instancia de M1.

Puede evitar que al cambiar ligeramente su diseño y la incrustación de un puntero (o un puntero inteligente, si se puede usar esos) a una instancia de I1 lugar:

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

EDIT: Después de leer su código, creo que la forma más simple y limpia de resolver su problema es pasar la habitación actual al método Execute() de su comando, por ejemplo algo como:

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

¿qué representa el sc_? ¿Puedo usarlo así como así? – user522767

+0

@user, 'sc_' es un parámetro constructor, necesario para crear una instancia de' M1'. En mi ejemplo, debe apuntar a una instancia de una clase concreta derivada de 'I1' y proporcionar una implementación de' a() ',' b() 'y' c() '. P.ej. una instancia de 'I2' funcionaría. –

+0

¿Puedo enviarle mi código? Soy nuevo en C++ y realmente no puedo describir todo porque tengo un par de archivos en mi proyecto que están vinculados entre sí. – user522767

7

I1 es una clase abstracta porque tiene funciones puramente virtuales (= funciones sin definición).

No puede crear instancias de clases abstractas (porque ¿cómo funcionarían ?!), por lo tanto, una declaración como I1 a no funciona.

Después de editar la pregunta, parece que I1 no debe ser una clase abstracta, ya que proporcionó definiciones para los métodos. Si ese es el caso, simplemente elimine el = 0 después de las declaraciones de su método para que el código funcione.

+0

¿Qué puedo hacer? Por favor avise. – user522767

+1

Una solución común es utilizar un puntero (inteligente). Cuando inicializa ese puntero, crea una instancia de una clase derivada no abstracta. El puntero arroja implícitamente el caso más general (pero abstracto). Esto es válido porque la instancia real proporcionó las implementaciones del método, aunque el tipo de puntero no sabe qué implementaciones se aplican, eso se puede determinar en tiempo de ejecución. – Steve314

+0

¿Puedo enviarle mi código? Soy nuevo en C++ y realmente no puedo describir todo porque tengo un par de archivos en mi proyecto que están vinculados entre sí. – user522767

1

No puede crear una instancia para la clase abstracta (la clase que tiene una o más funciones virtuales puras). También hay otro problema. ¿Qué quiere que haga el compilador cuando llama a la función sc.a(dir) en la declaración de clase? La línea dir = 4 también es incorrecta, solo los miembros estáticos const de clase pueden inicializarse en la declaración de clase.

+0

En realidad, sería int dir = NORTH; donde NORTH se define en uno de los archivos incluidos como una variable global enum RoomId {EAST, WEST, SOUTH, NORTH} – user522767

Cuestiones relacionadas