James Kanze schreef:
On Apr 21, 9:53 pm, MathWizard <no_m...@please.comwrote:
>I have a question about returning an object in a function and calling a
copy constructor. As far as I understand, in the following code the copy
constructor may or may not be called, depending on the compiler:
>A what()
{
A my_A;
// do something with A.
return A;
}
Correct. Technically, the semantics specified by the standard
require that the copy constructor be called, but the standard
then gives the compiler explicit authorization to merge my_A and
the return value, and not call the copy constructor. (Note that
while not calling the copy constructor is the most visible
effect, there are others as well.) This is called NRVO: Named
Return Value Optimization.
>Suppose I have also a class B and a constructor for A from B:
A::A(const B& b);
>The question is now about the following code:
>A what()
{
B my_B;
// do something with B.
return B;
}
>As far as I can see, the constructor 'A::A(const B& b)' must be called
in order to return an object A. But is it possible that after that
constructor some (stupid) compiler decides that the copy constructor for
A must be called also?
The formal semantics are almost the same as above: first you
construct a temporary of type A, then you copy it into the
return value. Again, the standard explicitly allows the
compiler to elide the copy.
>Maybe some compiler might think that the copy
constructor must be called always if an object must be returned...
The copy constructor must be callable in both cases, or the code
is illegal. But I think that most compilers today elide the
copy in both cases.
--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
OK, thanks for the answer James. But it looks like I'm stuck with my
'solution'. The thing is, I have a function which was originally
implemented as:
A special_function()
{
A my_A;
// do something with A.
return A;
}
I call it 'special_function' here, because here, if the copy constructor
is called, the copy constructor must do something different than in all
other cases when the copy constructor for 'A' is called.
So I wanted to make a solution with:
A special_function()
{
B my_B;
// do something with B.
return B;
}
so that I could force to use the constructor from B to A and thus
implement the slightly different behaviour for returning from
'special_function'. But if the copy constructor for A is then called
afterwards, then things will crash again...
I also thought of setting a property in class A, like:
A special_function()
{
A my_A;
// do something with A.
// Prepare for special behaviour of the copy constructor.
A.in_special_function = true;
return A;
}
so that the copy constructor can test for that. But if NRVO is applied,
then the property remains set after A is returned and the special
behaviour of the copy constructor may be applied to the returned object
A somewhere in the code where I don't want it... For instance in the
situation:
void function2(A a)
{
}
function2(special_function());
Because the copy constructor is called when calling function2 while the
property 'A.in_special_function' may still be true at that time.
Any ideas maybe? Or is the description of my problem too vague :-)
Jeroen