4.4 C + + virtual destructor

Source: Internet
Author: User

Reference: http://www.weixueyuan.net/view/6373.html

Summarize:

A constructor cannot be declared as a virtual function, and a destructor can be declared as a virtual function.

After the destructor of the base class is declared as a virtual function, the destructor of the derived class automatically becomes the virtual destructor.

The base class's destructor is not defined as a virtual function, as in the case of the following example, a memory leak may occur. The reason is that the function is a compile-time binding, regardless of whether the base class pointer p points to a derived class object or a base class object, and the function that executes will be the base class.

In general, if there is a member variable in the base class that points to the dynamically allocated memory, and the code that releases the dynamically allocated memory is defined in the destructor of the base class, the destructor for the base class should be declared as a virtual function.

Only non-static member functions can be virtual, and static member functions cannot be declared as virtual functions.

In a class, constructors are used to initialize objects and related operations, and constructors cannot be declared as virtual functions because the object has not yet been created before executing the constructor, and the virtual function table does not yet exist, so it is not possible to query the virtual function table, so it is not possible to know which constructor to call.

The destructor is used to destroy the object when the corresponding resource is freed, and the destructor can be declared as a virtual function. Let's start with an example of the necessity of declaring a destructor as a virtual function.

Example 1:

#include <iostream>using namespacestd;class Base{ Public:    Base(); ~Base();Private:    int*A;};classDerived Public Base{ Public: Derived (); ~derived ();Private:    int*b;};Base::Base() {cout<<"Base constructor!"<<Endl; A=New int[Ten];}Base::~Base() {cout<<"Base destructor!"<<Endl; Delete[] A;} Derived::d erived () {cout<<"derived constructor!"<<Endl; b=New int[ +];} Derived::~derived () {cout<<"derived destructor!"<<Endl; Delete[] b;}intMain () {Base*p; P=Newderived; Deletep; return 0;}

The

defines two classes in this class, a base class, a derived class, and its own constructors and destructors are defined in both derived and base classes. There is one int pointer member variable in the base class and the derived class, in the constructor of the base class, the pointer variable A is assigned 10 int space, and the destructor of the base class is used to release the space pointed to by a, in the constructor of the derived class, the pointer member variable is assigned 1000 integral space. The destructor of the derived class is to free the storage space pointed to by the B pointer. In the main function, we create a pointer to a base class type, pointer to a derived class object, and then release the storage space of the object to which the P pointer points. The results of the final program run as follows:
    Base constructor!
    derived constructor!
    Base destructor!

Watcher runs the results, the program prints out "base constructor!" This string of characters means that the constructor of the base class is called, and then the "derived constructor!" is printed. This string of characters, as well as the constructor of the derived class, is also called. When we create a derived class object with the new operator, we call the base class constructor before invoking the derived class constructor, and the program output is consistent with what we expect. At this point the member variable a of the base class is assigned 10 integral storage spaces through the constructor, and the member variable B of the derived class is assigned 1000 integral storage spaces through the constructor. Then the program prints out "base destructor!". String, which indicates that the destructor of the base class is called, and that the 10 integer memory space pointed to by the A pointer is freed. However, instead of invoking the destructor of the derived class, the destructor of the derived class is not called, and the 1000 integer storage space pointed to by the B pointer is not freed, . memory leak problem is definitely something that our program designers need to avoid. The problem with this example is that the destructor of the derived class is not called, in order to solve the problem, we declare the destructor of the base class as a virtual function, and the modified base class is defined as follows:

class Base {public:    base();     Virtual ~base(); Private :     int * A;};

After modifying the definition of the base class, the program runs the following result:
Base constructor!
Derived constructor!
Derived destructor!
Base destructor!

After the destructor of the base class is declared as a virtual function, the destructor of the derived class automatically becomes the virtual destructor , and in the main function the base class pointer p points to the derived class object, and when delete releases the storage space pointed to by the P pointer, the destructor of the derived class is executed . After the destructor of the derived class executes, the destructor of the base class is executed immediately, to release the resources consumed by the member variables inherited from the base class. As a result, there is no memory leak problem.

From this example we can clearly see the necessity of declaring a destructor as a virtual function, but it is not appropriate to declare all of the base class's destructors as virtual functions, regardless of 3,721. In general, if there is a member variable in the base class that points to the dynamically allocated memory, and the code that releases the dynamically allocated memory is defined in the destructor of the base class, the destructor for the base class should be declared as a virtual function.

Only non-static member functions can be virtual, and static member functions cannot be declared as virtual functions.

Example 1:

classtest{ Public :    VirtualTest () {a =New int[5];}//Error    Static voidg ();//OK    Virtual voidf ();//OK    Virtual Static voidH ();//Compile Error    Virtual~test () {Delete[] A;}//OKPrivate:    int*A;};

In this example, a test class is defined, there is a pointer member variable in the class A,test class has five member functions, in this case, the destructor and the ordinary member function F declaration as a virtual function is not a problem, the constructor and static member functions declared as virtual functions will have a compilation error, Both of these practices violate the C + + syntax.

4.4 C + + virtual destructor

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.