Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are usually two variants of the constructor (<em>not-in-charge</em> / <em>in-charge</em>) and three of the destructor (<em>not-in-charge</em> / <em>in-charge</em> / <em>in-charge deleting</em>).</p> <p>The <em>not-in-charge</em> ctor and dtor are used when handling an object of a class that inherits from another class using the <code>virtual</code> keyword, when the object is not the complete object (so the current object is "not in charge" of constructing or destructing the virtual base object). This ctor receives a pointer to the virtual base object and stores it.</p> <p>The <em>in-charge</em> ctor and dtors are for all the other cases, i.e. if there is no virtual inheritance involved; if the class has a virtual destructor, the <em>in-charge deleting</em> dtor pointer goes into the vtable slot, while a scope that knows the dynamic type of the object (i.e. for objects with automatic or static storage duration) will use the <em>in-charge</em> dtor (because this memory should not be freed).</p> <p>Code example:</p> <pre><code>struct foo { foo(int); virtual ~foo(void); int bar; }; struct baz : virtual foo { baz(void); virtual ~baz(void); }; struct quux : baz { quux(void); virtual ~quux(void); }; foo::foo(int i) { bar = i; } foo::~foo(void) { return; } baz::baz(void) : foo(1) { return; } baz::~baz(void) { return; } quux::quux(void) : foo(2), baz() { return; } quux::~quux(void) { return; } baz b1; std::auto_ptr&lt;foo&gt; b2(new baz); quux q1; std::auto_ptr&lt;foo&gt; q2(new quux); </code></pre> <p>Results:</p> <ul> <li>The dtor entry in each of the vtables for <code>foo</code>, <code>baz</code> and <code>quux</code> point at the respective <em>in-charge deleting</em> dtor.</li> <li><code>b1</code> and <code>b2</code> are constructed by <code>baz()</code> <em>in-charge</em>, which calls <code>foo(1)</code> <em>in-charge</em></li> <li><code>q1</code> and <code>q2</code> are constructed by <code>quux()</code> <em>in-charge</em>, which falls <code>foo(2)</code> <em>in-charge</em> and <code>baz()</code> <em>not-in-charge</em> with a pointer to the <code>foo</code> object it constructed earlier</li> <li><code>q2</code> is destructed by <code>~auto_ptr()</code> <em>in-charge</em>, which calls the virtual dtor <code>~quux()</code> <em>in-charge deleting</em>, which calls <code>~baz()</code> <em>not-in-charge</em>, <code>~foo()</code> <em>in-charge</em> and <code>operator delete</code>.</li> <li><code>q1</code> is destructed by <code>~quux()</code> <em>in-charge</em>, which calls <code>~baz()</code> <em>not-in-charge</em> and <code>~foo()</code> <em>in-charge</em></li> <li><code>b2</code> is destructed by <code>~auto_ptr()</code> <em>in-charge</em>, which calls the virtual dtor <code>~baz()</code> <em>in-charge deleting</em>, which calls <code>~foo()</code> <em>in-charge</em> and <code>operator delete</code></li> <li><code>b1</code> is destructed by <code>~baz()</code> <em>in-charge</em>, which calls <code>~foo()</code> <em>in-charge</em></li> </ul> <p>Anyone deriving from <code>quux</code> would use its <em>not-in-charge</em> ctor and dtor and take on the responsibility of creating the <code>foo</code> object.</p> <p>In principle, the <em>not-in-charge</em> variant is never needed for a class that has no virtual bases; in that case, the <em>in-charge</em> variant is then sometimes called <em>unified</em>, and/or the symbols for both <em>in-charge</em> and <em>not-in-charge</em> are aliased to a single implementation.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload