When I initialize an object of my class, both the default and copy constructor are called.
class A
{
public:
A (string s) { str = string (s); cout << "default" << endl; }
A (int n) { cout << "A (int n)" << endl; }
A (string s, int n) { cout << "A (string s, int n)" << endl; }
A (int n2, string s2) { cout << "A (int n2, string s2)" << endl; }
A (const A& a) { str = a.str; cout << "copy" << endl; }
inline void printA () { cout << str << endl; }
string str;
};
int main (void)
{
A a_1 = A ("con 1");
cout << endl;
A a_2 = "con 2";
cout << endl;
A a_3 = A (4);
A a_4 = A ("a_4", 10);
cout << endl;
A a_5 = A (11, "a_5");
cout << endl;
cin.get();
return 0;
}
Result:
default copy default A (int n) A (string s, int n) copy A (int n2, string s2) copy
Why do a_1, a_3, and a_4 call both the default and the copy constructors?
A_3 also has a single argument, but it doesn’t need copy constructor.
Constructs a temporary object by calling the constructor which takes a string as an argument,since the passed type is
const char *the compiler has to perform an implicit conversion first tostring() and then uses this temporary object to copy construct a newa_1object.Since there is an additional implicit conversion the compiler cannot optimize this and needs to make the call to the copy constructor.
Based on the comments and further research I am doubtful if the(above italicized)reasoning is correct.
@David suggests in his comments:
the copy can not be elided not because of implicit conversion, but rather because the conversion is explicit. That is, the compiler cannot optimize it because the code explicitly request the creation of the temporary and the copy construction.
However, neither @David nor Me are able to substantiate it through a Standard Citation.
constructs object
a_2by calling the appropriate constructor which takes string as an argument.The note in Case 1 also applies here:
Should Ideally Construct a temporary object by calling the constructor which takes integer as an argument and then use this temporary object to copy construct a new
a_3object as in case 1, but the compiler can optimize and directly construct the object by calling constructor which takes integer as one is available.Constructs a temporary object by calling the constructor which takes string and integer as an argument and then uses this temporary object to copy construct a new
a_4object.Constructs a temporary object by calling the constructor which takes integer and string as an argument and then uses this temporary object to copy construct a new
a_5object.Note that you do not have an Default constructor defined for your class.
You can achieve the same in a more efficient manner by avoiding the creation of the temporary and then copy constructing an object in above cases by not using the assignment(
=).My Initial answer was on attempt to explain the behavior but as I compile this on gcc-4.3.4 on Ideone, I find that gcc is intelligent enough to optimize the copy constructor call.None of the cases invoke the copy constructor.
The conclusion I come to is, Each compiler depending on its intelligence can or cannot optimize copy constructor calls in such as case, While the Standard does not require the compiler to perform such optimization each compiler evaluates such expressions depending on their capabilities.
If I am wrong on this please free to add me an comment with reasoning.