2016-04-10 32 views
5

Ho una classe derivata da un'altra, utilizzo una matrice di puntatori di classe base per contenere istanze della classe derivata, ma poiché l'array è della classe base, I non posso accedere ai membri appartenenti alla classe derivata con notazione del puntatore, è possibile per me accedere a questi membri con un semplice comando o dovrei semplicemente riscrivere la mia classe base per definire il membro e usarla solo nella classe derivata?Membro di accesso della classe derivata dal puntatore della classe base

Esempio:

class A { 
public: 
    int foo; 
}; 

class B : public A { 
public: 
    char bar; 
}; 

class C : public A { 
    int tea; 
}; 

int main() { 
    A * arr[5]; 
    arr[0] = new B; 

    char test = arr[0]->bar; //visual studio highlights this with an error "class A has no member bar" 

    return 0; 
} 
+1

Per quanto ne so non è possibile accedere al membro di una classe derivata dal puntatore di una classe base. Semplicemente perché la classe base non lo riconosce in alcun modo. Puoi comunque accedere al membro della classe base dal puntatore di una classe derivata perché la gerarchia dice ** i membri pubblici della classe base ora sono anche membri della classe derivata **. –

+0

Ma i dati tecnicamente esistono giusto? Posso usare l'offset di memoria per farlo? – Stephen

+2

Ecco a cosa servono i metodi virtuali. Se non hai ancora imparato a conoscere i metodi virtuali nella tua classe C++, ora è un'eccellente opportunità per farlo. –

risposta

6

non posso accedere ai membri appartenenti alla classe derivata con puntatore notazione

Ciò è di progettazione: non hai detto al compilatore che l'oggetto puntato da il puntatore è del tipo derivato.

è possibile per me per accedere a questi membri con un semplice comando

Si può fare se si esegue static_cast<B*>(arr[0]) se si è certi al 100% che i punti di puntatore B, ma soluzione fusione dovrebbe essere usato come ultima risorsa Invece, si dovrebbe ricavare una funzione di membro nella classe base, e fornire un'implementazione nella classe derivata:

class A { 
public: 
    int foo; 
    virtual char get_bar() = 0; 
}; 

class B : public A { 
    char bar; 
public: 
    char get_bar() { 
     return bar; 
    } 
}; 
+0

Il modo in cui ho progettato il mio algoritmo, saprò sempre quando il puntatore punta alla classe derivata. Quindi funziona perfettamente per quello di cui ho bisogno. Ho provato un cast dinamico ma non pensavo di fare un cast statico, grazie. Segnalo come la risposta. – Stephen

+0

Hai accettato la risposta per tutti i motivi sbagliati. Dovresti seriamente considerare l'utilizzo di una funzione virtuale. –

+0

Questa domanda era per un programma, molti dei quali erano già stati scritti. Avevo bisogno di questa risposta specifica come soluzione rapida. In futuro userò sicuramente funzioni virtuali per portare a termine il lavoro. – Stephen

0

In caso di codice, il vostro membro della classe derivata è privato. Quindi, non puoi accedervi dalla classe base. Se si desidera accedere, è necessario modificare il membro della classe derivata in "pubblico". Si dovrebbe risolvere il tuo codice come questo:

class B : public A { 
public: 
    char bar; 
}; 

int main() { 
A * arr[5]; 
arr[0] = new B; 

char test = static_cast <B *>(arr[0])->bar; //visual studio highlights this with an error "class A has no member bar" 
return 0; 

}

1

leggere su type-casting, è un aspetto molto importante di base e della lingua.

In breve, è sempre possibile eseguire il cast di un puntatore-base su un puntatore-a-derivato, quindi fare riferimento ai suoi membri pubblici univoci.

A * arr[5]; 
arr[0] = new B; 

char test = static_cast<B*>(arr[0])->bar; 

Tuttavia, l'ultima riga sopra è una dichiarazione valida anche se che A* non punta in realtà a un oggetto di tipo B. Se si prova su un oggetto C, questo verrà compilato e genererà un comportamento non definito durante il runtime.

Si deve tuttavia ricordare che di solito quando non si può essere certi del tipo di oggetto a cui si riferisce, un design migliore del programma avrebbe potuto prevenirlo dal primo posto. Un'affermazione comune dice che è vero per il casting di tipo in generale.

P.S. Nota che nel tuo codice, bar è un membro privato di class B (non intenzionalmente, presumo.Tutti i membri di un class sono privati ​​per impostazione predefinita), quindi non è possibile accedervi comunque al di fuori dell'implementazione di class B.

+0

Il casting non è lo strumento giusto per il lavoro e non è un aspetto di base se il paradigma di programmazione orientato agli oggetti, che è più importante di qualsiasi linguaggio specifico. Si prega di non utilizzare il casting per coprire un design OO inadeguato. –

+0

Credo che sia discutibile. E per mia comprensione, questa domanda non riguardava l'OOD. Era una domanda tecnica, e il tipo di casting è la risposta diretta alla domanda nel modo in cui è stata formata. Se conosci uno "strumento giusto per il lavoro" che non cambia argomento, ti preghiamo di farlo. –

+0

"Credo che sia discutibile". Io non. "Era una domanda tecnica". Era una domanda di qualcuno che ha bisogno di una guida, non di risposte tecnicamente corrette ma pericolose. –