Dichiarare un oggetto anche prima della creazione di quella classe
-
02-07-2019 - |
Domanda
Esiste un modo per dichiarare un oggetto di una classe prima che la classe venga creata in C ++? Lo chiedo perché sto cercando di utilizzare due classi, la prima deve contenere un'istanza della seconda classe al suo interno, ma la seconda classe contiene anche un'istanza della prima classe. Mi rendo conto che potresti pensare che potrei entrare in un ciclo infinito, ma in realtà ho bisogno di creare e istanza della seconda classe prima della prima classe.
Soluzione
Non puoi fare qualcosa del genere:
class A {
B b;
};
class B {
A a;
};
Il problema più ovvio è che il compilatore non sa quanto è necessario per rendere la classe A, perché la dimensione di B dipende dalla dimensione di A!
Tuttavia, puoi farlo:
class B; // this is a "forward declaration"
class A {
B *b;
};
class B {
A a;
};
La dichiarazione della classe B come dichiarazione diretta consente di utilizzare i puntatori (e i riferimenti) a quella classe senza avere ancora l'intera definizione della classe.
Altri suggerimenti
Non puoi dichiarare un'istanza di una classe indefinita ma puoi dichiarare un puntatore a una:
class A; // Declare that we have a class A without defining it yet.
class B
{
public:
A *itemA;
};
class A
{
public:
B *itemB;
};
C'è una soluzione elegante utilizzando modelli.
template< int T > class BaseTemplate {}; typedef BaseTemplate< 0 > A; typedef BaseTemplate< 1 > B; // A template<> class BaseTemplate< 0 > { public: BaseTemplate() {} // A constructor B getB(); } // B template<> class BaseTemplate< 1 > { public: BaseTemplate() {} // B constructor A getA(); } inline B A::getB() { return A(); } inline A B::getA() { return B(); }
Questo codice funzionerà! Quindi, perché lo fa lavoro? Il motivo ha a che fare con il modo i modelli sono compilati. Modelli ritardare la creazione della funzione firme fino a quando non si utilizza effettivamente il file modello da qualche parte. Ciò significa che né getA () né getB () avranno le loro firme sono state analizzate fino a dopo entrambe le classi A e B sono già state pienamente dichiarato. Questa è la magia di questo metodo.
È vicino a quello che vuoi: la prima classe contiene la seconda classe, ma la seconda classe (che deve essere creata per prima) ha solo un riferimento alla prima classe?
Questo si chiama riferimento incrociato. Vedi qui un esempio.