class - Determine which copy constructors is called in C++ code -
i have written simple c++ class example 1 non-param constructor, 1 param constructor, 2 copy constructors, 1 assignment operator , 1 plus operator.
class complex { protected: float real, img; public: complex () : real(0), img(0) { cout << "default constructor\n"; } complex (float a, float b) { cout << "param constructor" << << " " << b << endl; real = a; img = b; } // 2 copy constructors complex( const complex& other ) { cout << "1st copy constructor " << other.real << " " << other.img << endl; real = other.real; img = other.img; } complex( complex& other ) { cout << "2nd copy constructor " << other.real << " " << other.img << endl; real = other.real; img = other.img; } // assignment overloading operator void operator= (const complex& other) { cout << "assignment operator " << other.real << " " << other.img << endl; real = other.real; img = other.img; } // plus overloading operator complex operator+ (const complex& other) { cout << "plus operator " << other.real << " " << other.img << endl; float = real + other.real; float b = img + other.img; return complex(a, b); } float getreal () { return real; } float getimg () { return img; } };
i used class in main this:
int main() { complex a(1,5); complex b(5,7); complex c = a+b; // statement 1 system("pause"); return 0; }
result printed as:
param constructor 1 5 param constructor 5 7 plus operator 5 7 param constructor 6 12
i think copy constructor must used in statement 1, dont know 1 called. please tell me one, , why? lot
the compiler eliding call (actually, two calls) copy constructor. allowed (but not mandated!) per paragraph 12.8/31 of c++11 standard if constructor or destructor have side effects:
when criteria met, implementation allowed omit copy/move construction of class object, even if constructor selected copy/move operation and/or destructor object have side effects. [..] elision of copy/move operations, called copy elision, permitted in following circumstances (which may combined eliminate multiple copies):
— in
return
statement in function class return type, when expression name of non-volatile automatic object (other function or catch-clause parameter) same cv-unqualified type function return type, copy/move operation can omitted constructing automatic object directly function’s return value[...]
— when temporary class object has not been bound reference (12.2) copied/moved class object same cv-unqualified type, copy/move operation can omitted constructing temporary object directly target of omitted copy/move
if compiler did not elide calls copy constructor, first 1 picked twice, i.e. 1 following signature:
complex( const complex& other )
the reason that:
the value returned
operator +
copy-initialized temporary (complex(a, b)
), , lvalue referencesconst
can bind temporaries. things different ifoperator +
written so:complex operator+ (const complex& other) { // ... complex c(a, b); return c; }
in case, second copy constructor called, since
c
notconst
-qualified , lvalue, can bound lvalue reference non-const
;object
c
inmain()
being copy-constructed rvalue (the value returnedoperator +
temporary). true no matter howoperator +
returnscomplex
object, long returns value. therefore, first copy constructor picked whenever copy elision not performed.
if using gcc , want verify behavior, try setting -fno-elide-constructors
compilation flag (clang supports too, version 3.2 had bug , don't know whether fixed).
Comments
Post a Comment