Valid tive C ++ (7) declares virtual destructor for the polymorphism base class or Not

Source: Internet
Author: User

Problem focus:

If a delete statement has been executed on an object, Will Memory leakage still occur?

Let's take a look at a demo:
// Timer class TimeKeeper {public: TimeKeeper ();~ TimeKeeper () ;}; class AtomicClock: public TimeKeeper {......}; // atomic clock class WaterClock: public TimeKeeper {......}; // water meter class WristWatch: public TimeKeeper {......}; // watch // design the Factory function for the user to use TimeKeeper * ptk = getTimeKeeper (); // The Factory function will "return a pointer to the parent class, point to the new subclass object "...... delete ptk; // Point! Release it to avoid resource leakage

What is the problem with the demo above? Memory leakage? This object has been deleted later. Will the memory leak? The answer is yes. Let's analyze it. Problem description: The pointer returned by the getTimeKeeper () function points to a derived class object, and the subclass object is released through its parent class pointer, its parent class has a non-virtual destructor. Result: C ++ points out that when a subclass object is deleted by its parent class Object Pointer, the destructor of the parent class object is non-virtual. The result is: Normally, the parent class of the object is destroyed, and the Child class is not destroyed. Solution: The destructor of the parent class are declared as virtual functions. Demo:
Class TimeKeeper {public: TimeKeeper (); virtual ~ TimeKeeper ();...}; // use TimeKeeper * ptk = getTimeKeeper ();... delete ptk;

In this case, when we define a class in the future, we will declare all its destructor as virtual functions to avoid the "local destruction" problem. But this is not a good idea. (PS: thanks to my teacher for letting me know about the virtual function table...). Let's take a look at a demo first.
class Point {public:    Point(int xCoord, int yCoord);    ~Point();private:    int x, y;};
If int occupies 32 bits, the Point object can be inserted into a 64bit cache. Such a Point object can be passed as a "64-bit volume" to functions written in other languages such as C or Fortran.
But if the Destructor is declared as virtual, what will happen? The virtual keyword can be used to determine which virtual function is called at runtime. This powerful function is obviously costly. This cost is the extra space required to store the virtual function table-the compiler looks for the appropriate function pointer in it and points to the pointer (stored in the object ). (The implementation details of the virtual function table are not discussed here) so if you declare the Destructor as virtual, the volume of the Point object will increase: in the 32bit computer architecture, 64 bits is occupied to 96 bits (with the virtual function pointer 32 bits ). Therefore, adding a virtual function will increase the object by 50% ~ 100%. This object in C ++ cannot be compatible with this object in C. If it is not explicitly compensated, the two cannot be compatible.
To sum up, it is wrong to blindly declare the destructor of all classes as virtual or non-virtual.
Note that you should not attempt to inherit a standard container or other "non-virtual destructor", although it looks very convenient. As shown below:
Class SpecialString: public std: string {......}; // if you write a piece of code like this, it is definitely the beginning of your tragedy. SpecialString * pss = new SpecialString ("Hello world! "); Std: string * ps; ...... ps = pss; ...... delete ps; // partially destroyed, causing resource leakage

If you are sure that this class is used as a parent class, it may be a good idea to declare an abstract class. Let's look at a demo.
Class AWOV {public: virtual ~ AWOV () = 0 ;}; AWOV ::~ AWOV () {}// definition of pure virtual functions
Note that the definition of the Destructor is required. Otherwise, the compiler reports an error. (Because the compilation will not generate one for you)
Summary: A parent class with polymorphism should declare a virtual destructor. If a class has any virtual function, it should have a virtual destructor. If a class is not designed to be used as a parent class, or is not designed to have polymorphism, virtual destructor should not be declared. Of course, there should be no classes that inherit it.



Related Article

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.