开发者

No call to the copy constructor

Consider this:

#include <iostream>

struct A{
   A(){
       std::cout << "Create empty A" << std::endl;
   }

   A(const A& a){
       // Why is this never called??
       std::cout << "Never called" << std::endl;
   }
};

A genA() {
   A a;
   return a;
}

int main(int argc, const char *argv[])
{
   A a(genA()); // Expected to call copy constructor
   return 0;
}

Why is the copy constructor not called?

What sh开发者_运维技巧ould I do if I want to ensure that "Never called" is printed on the screen every time I copy A.


This is called as Return value optimization.
Compiler can optimize your code so that it bulds the object directly in the location where it would have been copied too. Thus there will be no reason to use the copy constructor.

Note: The standard explicitly allows it do so.


One way you can force the compiler to avoid RVO is to not return by value - e.g.

#include <iostream>
#include <memory>

struct A{
   A() {
       std::cout << "Create empty A" << std::endl;
   }

   A(const A& a) {
       // This will be called now
       std::cout << "Never called" << std::endl;
   }
};

std::auto_ptr<A> genA() {
   return std::auto_ptr<A>(new A);
}

int main(int argc, const char *argv[])
{
   A a(*(genA().get())); // this will trigger the copy-ctor
   return 0;
}

Though this is a horrible hack. I would instead ask why you want to do this? and if you are hoping to put some side-effects into the constructor, urge you to think otherwise.


Copy constructor invocations can be elided (even if they contain side effects), the standard allows that ([12.2]).

EDIT:

I suggest that you do not try to fight it in real world code.

If you just want to see the copy ctor executed in some example/turorial code, then it usually helps not to compile with optimization. Some compilers even have switches that help to avoid that. For GCC it should be -fno-elide-constructors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜