2010-05-06 15 views
5

estoy haciendo un simple juego de consola en C++miembros de la clase Acceso a los derivados con un puntero de clase base

me gustaría saber si puedo acceder a los miembros de la clase 'entPlayer' durante el uso de un puntero que apunta a la clase base ('Entity'):

class Entity { 
public: 
    void setId(int id) { Id = id; } 
    int getId() { return Id; } 
protected: 
    int Id; 
}; 

class entPlayer : public Entity { 
    string Name; 
public: 
    void setName(string name) { Name = name; } 
    string getName() { return Name; } 
}; 

Entity *createEntity(string Type) { 
    Entity *Ent = NULL; 
    if (Type == "player") { 
     Ent = new entPlayer; 
    } 
    return Ent; 
} 

void main() { 
    Entity *ply = createEntity("player"); 
    ply->setName("Test"); 
    ply->setId(1); 

    cout << ply->getName() << endl; 
    cout << ply->getId() << endl; 

    delete ply; 
} 

¿Cómo podría llamar a ply-> setName, etc.?

O

Si no es posible, de esa manera, lo que sería una manera mejor?

+1

Disculpa, tuve que editar el formato de tu código. ¡Las líneas en blanco hicieron tu código realmente alto! Otro pequeño comentario sobre tu código: sigue una convención de nombres consistente, p. AllClassNamesLikeThis, y parameter_names_like_this. Otra queja: te patearás en el trasero más tarde con abreviaturas como "ent". Honestamente, no puedo decir qué se supone que entPlayer es. Creo que lo que quieres decir es solo "Jugador", o si te sientes prolijo "PlayerEntity". – allyourcode

Respuesta

11

Es posible mediante el uso de un elenco. Si usted sabe que es un hecho que el puntero de la clase base a un objeto de la clase derivada, se puede utilizar static_cast:

Entity* e = /* a pointer to an entPlayer object */; 
entPlayer* p = static_cast<entPlayer*>(e); 
p->setName("Test"); 

Si usted no sabe a ciencia cierta, entonces usted necesita para utilizar y probar el dynamic_cast Resultado para ver que no es nulo. Tenga en cuenta que solo puede usar dynamic_cast si la clase base tiene al menos una función virtual. Un ejemplo:

Entity* e = /* a pointer to some entity */; 
entPlayer* p = dynamic_cast<entPlayer*>(e); 
if (p) 
{ 
    p->setName("Test"); 
} 

Dicho esto, sería mucho mejor para encapsular la funcionalidad de su clase con el polimorfismo (es decir, las funciones virtuales).

Hablando de funciones virtuales, su jerarquía de clases como implementador tiene un comportamiento indefinido: solo puede eliminar un objeto de un tipo derivado a través de un puntero a una de sus clases base si la clase base es un destructor virtual. Por lo tanto, debe agregar un destructor virtual a la clase base.

+0

Tenía una pregunta relacionada, que responde a esta pregunta: D Lo que quería saber era "¿Cómo puedo saber si mi puntero base realmente apunta a un objeto derivado?".La respuesta que estoy recopilando es use dynamic_cast (solo funciona si la clase base tiene una función virtual). Luego, mira si el resultado es NULO. #victorybaby – allyourcode

+0

Esto también (parcialmente) responde a otra pregunta que he tenido durante un tiempo sobre C++: ¿Cuál es la diferencia entre los distintos tipos de moldes? ¡Seguro que parece ser un buen número de ellos! – allyourcode

0

Usted puede hacer un elenco dinámico:

entPlayer * pPlayer = dynamic_cast<entPlayer *>(pointer_to_base); 

Esto (si tiene éxito) dan como resultado un puntero derivada.

De lo contrario, se devuelve NULL.

1

yo consideraría hacer algo como esto:

public: 
void setId(int id) 
{ 

    Id = id; 

} 

void virtual setName(string name) = 0; // Virtual Function 
string virtual getName() = 0; // Virtual Function 

int getId() { return Id; } 

protected: 
    int Id; 

}; 

class entPlayer : public Entity { 

    string Name; 

public: 
    entPlayer() { 

     Name = ""; 
     Id = 0; 

    } 

    void entPlayer::setName(string name) { // Must define function 

     Name = name; 
} 

string entPlayer::getName() { return Name; } // again must define function here 

}; 
0

C++ hace que lo que está tratando de hacer muy incómodo, porque esto no es probablemente lo que debe hacer, y que está tratando de llevar a buen diseño orientado a objetos. De hecho, de forma predeterminada, compilers often disable run-time type information (RTTI), que se necesita para que dynamic_cast funcione.

Sin conocer su contexto más amplio, es difícil decir qué debe hacer en su lugar. Lo que puedo decir es que si querías un puntero más específico, deberías haber puesto un anillo en él que casi seguro no deberías usar una función que devuelva Entity*, y probablemente haya un mejor enfoque.

Cuestiones relacionadas