03.01.2013 Views

Chapter 1

Chapter 1

Chapter 1

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

When a subsequent PopAndDestroy() happens, this function can only call the destructor<br />

of a CBase-derived object. We have already noted that CBase::operator new() zero<br />

initializes all member variables; now we meet CBase's second important property:<br />

Important<br />

CBase's destructor is a virtual function.<br />

This means that any object derived from CBase can be pushed to the cleanup stack and,<br />

when it is popped and destroyed, its destructor is called (as you would expect).<br />

Important<br />

The cleanup stack and C++ destructors make it very easy for a<br />

programmer to handle cleanup. Use the cleanup stack for objects<br />

pointed to only by C++ automatics. Use the destructor for objects<br />

pointed to by member variables. It just works. You very rarely need to<br />

use TRAP(). The resulting code is easy to write, compact, and efficient.<br />

6.2.7 Two-phase Construction<br />

The cleanup stack is used to hold pointers to heap-based objects so that they can be<br />

cleaned up if a leave occurs. This means that you must have the opportunity to push objects<br />

to the cleanup stack. One key situation in which this would not be possible when using<br />

normal C++ conventions is in between the allocation performed by new, and the invocation<br />

of a C++ constructor that follows the allocation.<br />

This problem requires us to invent a new rule that C++ constructors cannot leave. We also<br />

need a work-around: two-phase construction.<br />

C++ constructors must not leave<br />

Let's see what happens if we allow C++ constructors to leave. memorymagic has a class<br />

called CY that contains a member variable that points to a CX. Using conventional C++<br />

techniques, we allocate the CX from the constructor<br />

class CY : public CBase<br />

{<br />

public:<br />

CY();<br />

public:<br />

~CY();<br />

CX* iX;<br />

};<br />

CY::CY() {<br />

iX = new(ELeave) CX;<br />

}<br />

CY::~CY()<br />

{<br />

delete iX;<br />

}<br />

memorymagic's Use 4 menu item calls cleanup-friendly code, as follows:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!