C ++ Access derivato membro della class dal puntatore della class base

Se alloco un object di una class Derived (con una class base di Base ) e memorizzo un puntatore a quell’object in una variabile che punta alla class base, come posso accedere ai membri della class Derived ?

Ecco un esempio:

 class Base { public: int base_int; }; class Derived : public Base { public: int derived_int; }; Base* basepointer = new Derived(); basepointer-> //Access derived_int here, is it possible? If so, then how? 

No, non è ansible accedere a derived_int perché derived_int è parte di Derived , mentre basepointer è un puntatore a Base .

Puoi farlo al contrario:

 Derived* derivedpointer = new Derived; derivedpointer->base_int; // You can access this just fine 

Le classi derivate ereditano i membri della class base, non il contrario.

Tuttavia, se il tuo basepointer stava puntando a un’istanza di Derived potresti accedervi tramite un cast:

 Base* basepointer = new Derived; static_cast(basepointer)->derived_int; // Can now access, because we have a derived pointer 

Tieni presente che dovrai prima modificare l’eredità in public :

 class Derived : public Base 

Stai ballando sul campo minato qui. La class base non può mai sapere che in realtà è un’istanza derivata. Il modo più sicuro per farlo sarebbe quello di introdurre una funzione virtuale nella base:

 class Base { protected: virtual int &GetInt() { //Die horribly } public: int base_int; }; class Derived : Base { int &GetInt() { return derived_int; } public: int derived_int }; basepointer->GetInt() = 0; 

Se basepointer punti come qualcosa di diverso da un Derived , il tuo programma morirà in modo orribile, che è il risultato voluto.

In alternativa, puoi usare dynamic_cast(basepointer) . Ma hai bisogno di almeno una funzione virtuale nella Base per questo, e preparati ad affrontare uno zero.

Il static_cast<> , come alcuni suggeriscono, è un modo sicuro per spararti ai piedi. Non contribuire al vasto nascondiglio delle storie dell’orrore relative alla “non sicurezza delle famiglie linguistiche C”.

puoi usare CRTP

in pratica usi la class derivata nel modello per la class base

È ansible permettendo alla class base di conoscere il tipo di class derivata. Questo può essere fatto facendo della class base un modello di tipo derivato. Questo idioma C ++ si chiama modello modello curiosamente ricorrente .

Conoscendo la class derivata, il puntatore della class base può essere convertito staticamente in un puntatore al tipo derivato.

 template class Base { public: int accessDerivedField() { auto derived = static_cast(this); return derived->field; } }; class Derived : public Base { public: int field; }; int main() { auto obj = new Derived; obj->accessDerivedField(); } 

// se sapete quale class derivata userete

Derived * derivedpointer = dynamic_cast basepointer;

// quindi è ansible accedere alla class derivata utilizzando derivedpointer