|
Let's say that class X has a data member of type Y and class Y has a data member of type X. We can define these classes in the following manner:
//partial definition of X: class X; class Y { X* x; // ...... }; //complete definition of X: class X { Y* y; // ...... };
But you have to be careful about the following: In the definition of Y, you cannot call the constructors or the destructors or any other member functions of X because they have not yet been defined.
To get around this problem, you only declare function prototypes in Y, especially for those functions that need the functionality of X. You then supply implementations for these function prototypes after X is defined.
For example, the following is wrong because it calls the destructor of X in line (A)-before the X's destructor is defined.
//partial definition of X: class X; class Y { X* x; public: // ~Y(){ delete x; } // WRONG //(A) }; // complete definition of X: class X { Y* y; // ...... };
But the following is correct:
//partial definition of X: class X; class Y { X* x; // ...... public: //only the prototype provided here for destructor: ~Y(); }; //complete definition of X: class X { Y* y; // ...... }; //complete def of Y's destructor provided separately: Y::~Y(){ delete x; }
|