the beauty of destruction pete isensee microsoft [email protected] game developers conference march...
TRANSCRIPT
![Page 2: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/2.jpg)
C++ Destructor Definition• One• Special• Deterministic• Automatic• Symmetric• Member• Function
• With• A special name• No parameters• No return type
• Designed to• Give last rites• Before object
death
![Page 3: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/3.jpg)
Language ComparisonLanguage
Name Notation
Deterministic
Notes
C n/a n/a n/aC++ Destructor ~T() YesC++/CLI Destructor ~T() YesC++/CLI Finalizer !T() No Called during
GCC# Finalizer ~T() No Called during
GCC# IDisposabl
eDispose()
No
Java Finalizer finalize() No Called during GC
![Page 4: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/4.jpg)
When Destructors Are InvokedScenario Destructor called NotesNamed automatic Scope exitFree store delete operator Prior to memory being freedStatics and globals Program exit Reverse order of constructionArray elements From last element to firstSTL container elements
Unspecified order
Temporary End of expression in which it was created
If bound to reference or named object, when object exits scope
Exception thrown Stack unwindingExplicit dtor p->~T();exit() For global & static objects Reverse order of constructionabort() No; global & static dtors not
called
![Page 5: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/5.jpg)
Order of Destruction• Rule of Thumb: Reverse order of
construction• Specifically:
1. Destructor body2. Data members in reverse order of declaration3. Direct non-virtual base classes in reverse
order4. Virtual base classes in reverse order
![Page 6: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/6.jpg)
Destruction Order Exampleclass Human : Ego, virtual Id {};class Vulcan : Katra, Kolinahr {};class Spock : Human, Vulcan{ Tricorder t; Phaser p; };Spock s;
SpockTricorderPhaserHuman
Ego
Id
VulcanKatra
Kolinahr
61
32
7
4
9
8
5
![Page 7: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/7.jpg)
Implicit Destructors• Not specified by the programmer• Inline by default• Public• Recommended for struct-like POD-only
objects• For everything else, avoid implicit
destructors • Better debugging• Improved perf analysis
![Page 8: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/8.jpg)
Trivial Destructors• Destructors that never ever do anything
• Compiler can optimize away
• Requirements• Implicit• Not virtual• All direct base classes have trivial dtors• All non-static members have trivial dtors
![Page 9: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/9.jpg)
Virtual Destructors• Guarantee that derived classes get cleaned up• Rule of thumb: if class has virtual functions, dtor
should be virtual• If delete on a Base* could ever point to a Derived*
• Perf: Obj with any virtual funcs includes a vtable ptr
• Idiom exceptions: mixin classes• Pure signals abstract class
virtual ~T() = 0 { }
![Page 10: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/10.jpg)
Partial Construction & Destruction• Dtors are only called for fully constructed
objs• If a ctor throws, obj was not fully
constructed• Object dtor will not be called• But fully constructed subobjects will be
destroyed
• Always use RAII within ctors• Resource Acquisition Is Initialization
![Page 11: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/11.jpg)
Virtual Functions in Destructors• Virtual functions are not virtual inside
dtorsclass Helmsman {public: // Red alert! virtual ~Helmsman() { Release(); }protected: virtual void Release() {}};class Sulu : public Helmsman { … };
![Page 12: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/12.jpg)
C++ Exception Handling• Destructors : Exceptions :: Spock : Kirk• Wrap any function that acquires a resource
in a class where dtor releases the resource• Never allow an exception to exit a dtor
• Best: don’t throw in the dtor• OK: wrap throwing code in a try/catch
• Good advice even if you don’t use C++EH
![Page 13: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/13.jpg)
Multithreading• You are responsible for protecting objects
and their contents• Sharing an object across threads
• Use shared_ptr• Or some other reference counting• Or otherwise ensure only one thread can
destroy
• Protect shared memory (global counters, ref counts) in dtors
![Page 14: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/14.jpg)
delete and Destructorsdelete p is a two-step process. Pseudo code:
// T* p = new T(…); ≈T *p = (T*)operator new( sizeof(T) );new (p) T(…); // placement new
// delete p ≈if( p != NULL ) { p->~T(); // explicit destructor operator delete( p );}
![Page 15: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/15.jpg)
Explicit Destructors• Destructors can be called directly• Avoid 99.99% of the time• Very powerful for custom memory
scenarios• Example uses
• w/ placement new• STL allocators
void* p = Alloc(…);Kirk* pk = new (p) Kirk;pk->~Kirk();Free( pk );
![Page 16: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/16.jpg)
std::allocator• Allocators enable custom STL container
memory• Two key destructive functions
void allocator::destroy( T* p ){ ((T*)p)->~T(); } // default impl.
void allocator::deallocate( T* p, size_type ){ operator delete( p ); } // default impl.
![Page 17: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/17.jpg)
Case Study: std::vectortemplate <class T> vector::~vector(){ if( m_pFirst != 0 ) { for( T* p = m_pFirst; p != m_pLast; ++p ) m_Alloc.destroy( p ); m_Alloc.deallocate( m_pFirst ); }}
![Page 18: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/18.jpg)
shared_ptr• Templated non-intrusive deterministically
referenced-counted smart pointer
Object Category Owned By Their Destroyed WhenAutomatic Block Control Leaves BlockData Members Parent Parent diesElements Container Container diesDynamically Allocated shared_ptrs All shared_ptrs die
shared_ptr<T> sp( new T(…) );
![Page 19: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/19.jpg)
Case Study: tr1::shared_ptrtemplate <class T>shared_ptr::~shared_ptr(){ if( m_pRep != NULL ) // if we’re not a NULL ptr { // and we’re the last owner if( InterlockedDecrement( &m_pRep->RefCount ) == 0 ) { // dispose of the shared object delete m_pSharedPtr; // use deleter if specified // if we’re done with the control block if( InterlockedDecrement( &m_pRep->WeakRefCount ) == 0 ) delete m_pRep; // use allocator.destroy if specified } }}
![Page 20: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/20.jpg)
shared_ptr deleters• Deleter: a functor called on the stored raw
pointer when ref count hits zero
template <class T> struct Deleter{ void operator()( T* p ) { Free( p ); } };
Khan* p = Alloc(…);shared_ptr<Khan> sp( p, Free );shared_ptr<Khan> sp( p, Deleter<Khan>() );
![Page 21: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/21.jpg)
Destructor Idioms to Love• delete p• if (p!=NULL) free(p)• CloseHandle()• DeleteCriticalSection()• SetEvent()• pComPtr->Release()• --refCount• InterlockedDecrement(
)• flush()• try { Close() }
catch( … )• closesocket()• assert( … )• { }
![Page 22: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/22.jpg)
Destructor Gotchas: Red Alert• delete a; delete b• if( p != NULL ) delete p• m_Handle = NULL• Cleanup()• m_Member.Cleanup()• for( itr = v.beg(); itr != v.end(); ++itr ) delete *itr
![Page 23: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/23.jpg)
Case Study: Multiple owned resourcesstruct Uhura { X* p; Y* q; };// Red alert: leak potentialUhura::Uhura() : p(new X), q(new Y) { }Uhura::~Uhura() { delete p; delete q; }
struct Uhura { shared_ptr<X> sp; shared_ptr<Y> sq; };// SafeUhura::Uhura() : sp(new X), sq(new Y) { }Uhura::~Uhura() {}
![Page 24: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/24.jpg)
Performance• Destructors are called a LOT• They’re invisible in code• Streamline common dtors• The best dtor is empty• Inlining• Profile
}Lots o’ destruction here
![Page 25: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/25.jpg)
Enterprise::~Enterprise(){}
Case Study: Destructor TuningEnterprise::~Enterprise(){ Unload(); m_ReactorCore.Empty(); if( m_pOrdnance != NULL ) { delete m_pOrdnance; m_pOrdnance = NULL; } if( m_hAlert != NULL ) { CloseHandle(m_hAlert); m_hAlert = NULL; } for( int i = 0; i < m_CrewSize; i++ ) delete m_Crew[i];}
Enterprise::~Enterprise(){ delete m_pOrdnance; if( m_Alert != NULL ) CloseHandle( m_hAlert ); for( int i = 0; i < m_CrewSize; i++ ) delete m_Crew[i];}
![Page 26: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/26.jpg)
• Never own more than a single raw resource
• Never let any exceptions escape a dtor• Never call virtual funcs from a dtor• Avoid clearing data unnecessarily (e.g.
zeroing memory, setting ptrs to NULL)• Avoid implicit dtors for non-PODs• Avoid dtors that call other member funcs
Best Practices
![Page 27: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/27.jpg)
Best Practices: Do This• Embrace RAII: wrap any function that
acquires a resource in a class where the dtor releases
• Embrace shared_ptrs to avoid leaks and deletes
• Virtual dtor iff delete Base* could be a Derived*
• Validate state in dtors: guaranteed choke point
• The best destructor: an empty destructor• Second best: releasing a single resource
![Page 28: The Beauty of Destruction Pete Isensee Microsoft pkisensee@msn.com Game Developers Conference March 2009](https://reader030.vdocuments.net/reader030/viewer/2022032516/56649c3e5503460f948e9a7c/html5/thumbnails/28.jpg)
© 2009 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
http://www.xna.com
© 2009 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
http://www.xna.com