Hi all,

I don't quite understand the program print the following output.

class D
{
public:
        D(int j):i(j){printf("default %d\n", i);};
        D(const D& d):i(d.i){printf("copy %d\n", i);};
private:
        int i;
};

int main(int argc, char** argv)
{
        D d = 2;
        D d1 = D(23);
}

output:
default 2
default 23

I expect the copy constructor should be called after the temp object is created.
But why no "copy" is displayed?

>>I expect the copy constructor should be called after the temp object is created.
>>But why no "copy" is displayed?
Because the second line "D d1 = D(23);" is an explicit conversion. One way to look at it is in terms of optimization, that is, this is a trivial case where any compiler will understand that it is a waste to create a temporary D object and then assign-to or copy-construct object d1, it will optimize it away and simply call default D(int) constructor. Another way to look at it is in terms of semantics, that is, you can see this syntax as a way to make the intention to convert the integer value to a class D very clear and unambiguous (this is the purpose of the "explicit" keyword, to disable unintentional conversions). Essentially, if the compiler sees that the left-hand-side is a non-initialized object, it will try its best to find a constructor call in the right-hand-side that it can perform in-place instead of the default constructor call plus the assignment operator call.

As a rule of thumb, I would say that there is quite a bit of freedom given to the compiler when it comes to constructing objects (especially when temporaries are involved), unless you give it more specific instructions. This is why a particular sequence of constructor calls should never be a critical functional mechanism in your code (unless the construction/destruction is controlled more closely, e.g. in idioms such as factory-functions, non-copyable and RAII).

Thank you.
in summary, can I say "In theory, the copy constructor is called. However, a non-copy constructor is called depends on the compiler"?

>>can I say "In theory, the copy constructor is called. However, a non-copy constructor is called depends on the compiler"?

I really don't like the sound of that, but loosely speaking it is alright. More precisely I would say, for "D d1 = D(23);", that:
Syntactically, the copy-constructor is called to initialize d1 with the temporary "D(23)".
Semantically, 23 is explicitly converted to class D and assigned to d1.
Effectively, only the persistent result of the expression is guaranteed by the compiler, that is: d1 is guaranteed to hold the value 23 after this line.
In practice, the end result of what gets executed for that line is compile dependent and thus, any assumptions about what happens, other than the persistent result or effect mentioned above, are to be avoided if the code is to be well-behaved.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.