Object-Oriented Design Choices by Dingle Adair;
Author:Dingle, Adair;
Language: eng
Format: epub
Publisher: CRC Press LLC
Published: 2020-12-10T00:00:00+00:00
6.1.2When Inheritance Leaks Memory: C++ Destructors
C++ class designers must carefully manage heap memory as shown in Chapters 2 and 3. To avoid heap memory leaks and data corruption, the class designer must explicitly determine copy semantics: suppress copying, or efficiently support deep copying. A destructor must be defined for deallocation. The client is not responsible for invoking destructors; the compiler patches in destructor calls when stack objects go out of scope or when the delete operator is invoked for the release of heap objects.
C++ memory management becomes more complex when derived classes allocate heap memory. Destructors fire in reverse order of constructors. However, when delete is invoked through a polymorphic handle, binding affects outcome. To release a stack allocated Base class object, the compiler invokes only the Base destructor. To release a stack allocated Derived class object, the Derived destructor is invoked first, followed by the Base destructor. The Base destructor is implicitly invoked from the Derived destructor (a call to the Base destructor is the last instruction in the Derived destructor).
If a Base class pointer, myPtr, contains the address of a Base object, delete myPtr invokes the Base class destructor: no problem. What if myPtr holds the address of a Derived object? The compiler resolves calls based on the type of the pointer. With (default) static resolution of the destructor, only the Base class destructor is invoked so the Derived class destructor never runs. Failure to invoke the Derived class destructor leaks memory when the Derived class allocates heap memory. Ouch!
Example 6.2 illustrates such a hidden memory leak. Test this code yourself. When delete is called with Base class pointer b, the destructor call is statically bound so only â¼Base() fires. Through no fault of the client, the 500 integers allocated on the heap for a Derived object leak because â¼Derived() does not run. In statement #3, the client correctly calls delete for each heap object but with statically resolved destructors, only â¼Base() is invoked. The client has followed convention (match every new with delete) and yet there is an invisible memory leak.
With heterogeneous collections, Base class pointers often hold addresses of Derived class objects. To ensure that the appropriate destructor is called through a base class pointer, destructor invocation must be postponed. The (sub)type of the object whose address in held in the base class pointer must be examined at run-time in order to execute the proper destructor(s). The setup is the same as with other virtual methods. A Base class pointer may hold the address of Derived object so if the destructor is dynamically bound, the subtype resolved at run-time determines which destructor is called first (remember invocation of â¼Derived() automatically yields â¼Base()).
The fix is easy: make the Base destructor virtual. Thatâs all. No need to replicate Example 6.2. All code is the same except the keyword virtual is placed in front of the destructor in statement #1. Now the address of each class destructor will be placed in its vtab (because once virtual, always virtual!). Hence,
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Exploring Deepfakes by Bryan Lyon and Matt Tora(7750)
Robo-Advisor with Python by Aki Ranin(7648)
Offensive Shellcode from Scratch by Rishalin Pillay(6117)
Microsoft 365 and SharePoint Online Cookbook by Gaurav Mahajan Sudeep Ghatak Nate Chamberlain Scott Brewster(5052)
Ego Is the Enemy by Ryan Holiday(4960)
Management Strategies for the Cloud Revolution: How Cloud Computing Is Transforming Business and Why You Can't Afford to Be Left Behind by Charles Babcock(4440)
Python for ArcGIS Pro by Silas Toms Bill Parker(4192)
Elevating React Web Development with Gatsby by Samuel Larsen-Disney(3900)
Machine Learning at Scale with H2O by Gregory Keys | David Whiting(3640)
Learning C# by Developing Games with Unity 2021 by Harrison Ferrone(3286)
Speed Up Your Python with Rust by Maxwell Flitton(3232)
Liar's Poker by Michael Lewis(3228)
OPNsense Beginner to Professional by Julio Cesar Bueno de Camargo(3195)
Extreme DAX by Michiel Rozema & Henk Vlootman(3175)
Agile Security Operations by Hinne Hettema(3125)
Linux Command Line and Shell Scripting Techniques by Vedran Dakic and Jasmin Redzepagic(3110)
Essential Cryptography for JavaScript Developers by Alessandro Segala(3083)
Cryptography Algorithms by Massimo Bertaccini(3002)
AI-Powered Commerce by Andy Pandharikar & Frederik Bussler(2984)
