See the following code:
Class {
Public:
A () {pvalue = new int [100]; printf ("constructor of A/N ");}
~ A () {Delete [] pvalue; printf ("deconstructor of A/N ");}
PRIVATE:
Int * pvalue;
};
Class B {
Public:
~ B () {printf ("deconstructor of B/N ");}
};
Class C: Public B {
Public:
~ C () {printf ("deconstructor of C/N ");}
PRIVATE:
A;
};
Int main (INT argc, char * argv [])
{
C;
Return 0;
}
Class C is inherited from Class B. Class C aggregates an object of Class A. The destructor of class C does not call the destructor of Class A. Could you tell me: after this code is executed, will the destructor of Class A be called to release the memory? The test result is as follows:
Constructor of
Deconstructor of C
Deconstructor of
Deconstructor of B
It can be seen that C's destructor indeed calls the destructor of Class A, which is implicitly added by the compiler, and then calls the destructor of Class B, however, note that the compiler only adds a call to the Destructor for the base class and aggregate class. If the Member in C is a pointer to Class, the compiler will not call the destructor of Class. That is, if the member variable of class C is object pointer A * a, no class A object will be constructed whether it is to construct Class C objects or to analyze Class C objects, it does not parse Class A objects.
Then, if we change the main function:
Int main (INT argc, char * argv [])
{
B * B = new C;
Delete B;
Return 0;
}
Excuse me: Will this Code cause memory leakage? The execution result is as follows:
Constructor of
Deconstructor of B
What happened? After calling the constructor of A, the memory is allocated, but only the destructor of B is called. The destructor of C and A are not called, and the memory is not released. Why?
Some people may have seen the problem. The destructor of B and C should be virtual functions. Otherwise, because B is a pointer to Class B, delete B only calls the destructor of B. When the destructor of B and C are both virtual functions, the compiler calls the destructor of c Based on the object actually directed by B as the object of C. Make the following changes to the Code:
Class B {
Public:
Virtual ~ B () {printf ("deconstructor of B/N ");}
};
Class C: Public B {
Public:
Virtual ~ C () {printf ("deconstructor of C/N");} // because Class C's basic class B destructor are virtual functions, therefore, even if it is not virtual, the system will regard it as virtual. It is equivalent ~ C (), you can refer to this article on virtual functions.
PRIVATE:
A;
};
Run again and the result is correct:
Constructor of
Deconstructor of C
Deconstructor of
Deconstructor of B
Of course, to be more concise and clear, we can make the following changes to the above Code:
The header file contains the following content:
# Include "stdafx. H"
# Include <iostream>
; Using namespace STD;
Class
{
Public:
A ()
{
Cout <"Class A Constructing" <Endl;
}
Public:
~ A ()
{
Cout <"Class A destructing" <Endl;
}
};
Class B
{
Public:
B ()
{
Cout <"Class B constructing" <Endl;
}
Public:
Virtual ~ B ()
{
Cout <"Class B destructing" <Endl;
}
};
Class C: Public B
{
Public:
C ()
{
Cout <"Class C constructing" <Endl;
}
Public:
~ C () // The Destructor is not a virtual function, but the system still recognizes it as a virtual destructor ~ C () is equivalent.
{
Cout <"Class C destructing" <Endl;
}
PRIVATE:
A;
};
(1) If the main function is:
Int _ tmain (INT argc, _ tchar * argv [])
{
C;
Return 0;
}
The running result is:
Class B construcing
Class A construcing
Class C construcing
Class C destructing
Class A destructing
Class B destructing
Class B destructor are virtual functions. In fact, even if Class B destructor are not virtual functions, the results are still the same.
(2) If the main function is:
Int _ tmain (INT argc, _ tchar * argv [])
{
B * B = new C;
Delete B;
Return 0;
}
The running result is still:
Class B construcing
Class A construcing
Class C construcing
Class C destructing
Class A destructing
Class B destructing
(3) If you change the member variables of class C in the header file
A * A; that is, the member is not a class A object, but a pointer to Class A objects.
The main function is still the main function of (2 ).
The running result is:
Class B construcing
Class C construcing
Class C destructing
Class B destructing
That is to say, no matter whether a class C object is constructed or a class C object is parsed, it is not a matter of Class A objects.
Summary: this is a small example, but in actual programming, this small example still has some application value.