Note that there are some explanatory texts on larger screens.

plurals
  1. POStrange copy constructor
    text
    copied!<p>With the following C++ program:</p> <pre><code>#include &lt;memory&gt; #include &lt;iostream&gt; using namespace std; struct my_class{ int value; my_class(int id): value(id){ cout&lt;&lt;"constructing "&lt;&lt;id&lt;&lt;endl; cout&lt;&lt;"address is "&lt;&lt;static_cast&lt;const void *&gt;(this)&lt;&lt;endl; } my_class(const my_class &amp; a){ cout&lt;&lt;"construct copying "&lt;&lt;a.value&lt;&lt;endl; cout&lt;&lt;static_cast&lt;const void *&gt;(this)&lt;&lt;"&lt;-"&lt;&lt;static_cast&lt;const void *&gt;(&amp;a)&lt;&lt;endl; } my_class operator=(const my_class &amp; a){ cout&lt;&lt;"assignment copying "&lt;&lt;a.value&lt;&lt;endl; this-&gt;value = a.value; cout&lt;&lt;static_cast&lt;const void *&gt;(this)&lt;&lt;"&lt;-"&lt;&lt;static_cast&lt;const void *&gt;(&amp;a)&lt;&lt;endl; return *this; } ~my_class(){ cout&lt;&lt;"deleting "&lt;&lt;this-&gt;value&lt;&lt;endl; cout&lt;&lt;"address is "&lt;&lt;static_cast&lt;const void *&gt;(this)&lt;&lt;endl; } }; my_class f(){ cout&lt;&lt;"==in f=="&lt;&lt;endl; my_class temp(2); cout&lt;&lt;"==out f=="&lt;&lt;endl; return temp; } int main(){ cout&lt;&lt;"==in main=="&lt;&lt;endl; my_class a(1); a = f(); a.value++; cout&lt;&lt;"==out main=="&lt;&lt;endl; return 0; } </code></pre> <p>I got the following result:</p> <pre><code>==== ==in main== constructing 1 address is 0x28ff04 ==in f== constructing 2 address is 0x28ff0c ==out f== assignment copying 2 0x28ff04&lt;-0x28ff0c construct copying 2 0x28ff08&lt;-0x28ff04 deleting 2686868 address is 0x28ff08 deleting 2 address is 0x28ff0c ==out main== deleting 3 address is 0x28ff04 === </code></pre> <p>Can anyone explain to me what happens with the object at the address "0x28ff08" and the related copy constructing from object at the address "0x28ff04"? I really don't understand why the copy constructor is called here.</p> <hr> <p>I don't known if I get this correct, thus I want to further explain it in great detail. Anyone finds my mistakes please point them out.</p> <p>First, an image illustrates the details of the execution flow: <img src="https://i.stack.imgur.com/8LZPP.png" alt="the execution flow"></p> <p>(1). Create an object <code>a</code> with value 1;</p> <p>(2). Call function <code>f()</code>. Create an object <code>temp</code>, and the compiler finds that the object will be returned, so it is created directly in the caller's stack;</p> <p>(3). Assign the returned object of <code>f()</code> (i.e., <code>temp</code>) to object <code>a</code> by calling <code>operator=()</code> of <code>a</code>;</p> <p>(4). Object <code>a</code> is passed into <code>operator=()</code> as the parameter (rvalue) using the same variable name <code>a</code>.</p> <p>(5). The method <code>operator=()</code> is called on <code>main::a</code> (lvalue, with the abuse of notation), thus <code>this</code> in the function points to <code>main::a</code>, [!!this is the part that confused me];</p> <p>(6). <code>operator=()</code> changes the value of <code>main::a</code> to <code>a</code>'s value (i.e., from 1 to 2);</p> <p>(7). The compiler finds that the return type is not a reference, and <code>*this</code> already exists in <code>main()</code>, so it has to copy <code>*this</code> by calling the copy constructor. However, the copy constructor does not initialize the object, so an uninitialized object is created.</p> <p>(8). [!!not quite sure about this part] The lvalue and the resulting object is the same object, thus no object is really returned due to optimization.</p> <p>(9). The copied object is destroyed, according to @Mike Seymour, this object is created because the compiler cannot omit it because both the constructor and destructor actually do something (e.g. output the value and address).</p> <p>(10). When exiting <code>operator=()</code>, object <code>a</code> is destroyed.</p> <p>(11). When exiting <code>main()</code>, object <code>main::a</code> is finally destroyed.</p> <p>The above explains the output, however, my current understanding may not be correct. Please help me comprehend this if I am wrong. Thanks a lot.</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