The role of constructor and destructor when an object member is used in a derived class.

Source: Internet
Author: User

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.