Monday, May 13, 2013

Direct vs. Copy Initialization (Part 1)


#include "a_func.h"
#include <iostream>

int main(int argc, char** argv)
{
std::cout << "Case 1 A a1;\n";
A a1;

std::cout << "\nCase 2: A a2 = A();\n";
A a2 = A();

std::cout << "\nCase 3: A a3(a2);\n";
A a3(a2);

std::cout << "\nCase 4: A a4; a4 = a3;\n";
A a4;
a4 = a3;

std::cout << "\nCase 5: A getA() { return A(); } A a5 = getA();\n";
A a5 = getA();

std::cout << "\nCase 6: A getA2() { A a; return a; } A a6 = getA2();\n";
A a6 = getA2();

std::cout << "\nCase 7: A getA() { return A(); } A a7; a7 = getA();\n";
A a7;
a7 = getA();

std::cout << "\nCase 8: A getA2() { A a; return a; } A a8; a8 = getA2();\n";
A a8;
a8 = getA2();

std::cout << "\nCLEANUP!\n";
}


/**

RESULTS


Case 1 A a1;
    A()

Case 2: A a2 = A();
    A()

Case 3: A a3(a2);
    A(A const&)

Case 4: A a4; a4 = a3;
    A()
    A& operator=(A const&)

Case 5: A getA() { return A(); } A a5 = getA();
    A()

Case 6: A getA2() { A a; return a; } A a6 = getA2();
    A()

Case 7: A getA() { return A(); } A a7; a7 = getA();
    A()
    A()
    A& operator=(A const&)
    ~A()

Case 8: A getA2() { A a; return a; } A a8; a8 = getA2();
    A()
    A()
    A& operator=(A const&)
    ~A()

CLEANUP!
    ~A()
    ~A()
    ~A()
    ~A()
    ~A()
    ~A()
    ~A()
    ~A()

ANALYSIS:

Trying to clear up DIRECT vs. COPY initialization. It appears
that DIRECT INITIALIZATION requires NO CONVERSION. The
"constructor is available and is an exact match" [1]. The object
is initialized using a single constructor [2].

COPY INITIALIZATION is a little more difficult to understand.
It seems to consist of a series of "conversions". It looks
for ways to do the construction [1].

Case 1: It's obvious what's going on here, we construct an
        object of A using the default constructor. It is
        destroyed at the end of the scope of main. DIRECT.

Case 2: This one surprised me- only because I've been
        mistaken a lot. Due to the RETURN VALUE OPTIMIZATION,
        we avoid the cost of a copy constructor and an
        assignment operator.

Case 3: This is a simple copy constructor object. Definitely
        is a DIRECT INITIALIZATION.

Case 4: We cannot use the RETURN VALUE OPTIMIZATION in this
        case because we are not using COPY INITIALIZATION.
        We construct an object using DIRECT INITIALIZATION
        first, then we are forced to use the assignment
        operator.

Case 5, 6: This one surprised me. Only 1 constructor for A fires?
           The compiler must be doing something interesting
           under the hood. This is copy.

Case 7: This makes sense, we invoke constructor a7 once. Then
        we create another A when calling getA(), finally it
        uses the copy constructor to initialize. This is COPY
        INITIALIZATION.

case 8: We create a8 with a default constructor, then call getA2
        which creates another object of class A. Finally it uses
        the copy constructor- this is a chain of constructors
        and conversions so I think it is COPY.

It looks like Herb Sutter has some pretty interesting
articles. Going to go over them a bit more because there is
a lot more nuance to this than I originally thought. (This
post was supposed to be short!).

REFERENCES

[1] - http://stackoverflow/questions/1051379/is-there-a-difference-between-copy-initialization-and-direct-initialization

[2] - http://www.gotw.ca/gotw/036.htm

*/

No comments:

Post a Comment