Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

copy constructor c++ on temporary objects

#include <iostream>
using namespace std;

class A
{
    int x;

public:
    A(int c) : x(c) {}
    A(const A& a) { x = a.x; cout << "copy constructor called" << endl;}
};

class B
{
    A a;

public:
    B(int c) : a(c) {}
    B(const B& b) : a(b.a) { }
    A get_A() { return a;}
};

int main()
{
    B b(10);
    A a1 = b.get_A();

}

In the code above, I expected that 'copy constructor called' message would pop up twice because first, the b.get_A() will create a temporary object which invokes copy constructor (1) and second, it will copy its reference to a1 's copy constructor (2) , thus making two messages showing up.

However, the code actually results a single 'copy constructor called' message. Why?

like image 700
Jaebum Avatar asked May 26 '13 07:05

Jaebum


2 Answers

The C++ standard allows for the copy constructor to be elided in certain situations. Typically, this means if an object will be copy constructed from a temporary variable. It can be constructed in place.

In this case get_A(); has returned a copy, into a temporary. You then assign a1 to that temporary variable. The compiler is allowed to elide the extra copy and construct a1 in place with the return value of get_A().

This optimization can occur, even when the copy constructor has side effects.

Copy elision is the only allowed form of optimization that can change the observable side-effects. Because some compilers do not perform copy elision in every situation where it is allowed, programs that rely on the side-effects of copy/move constructors and destructors are not portable.

like image 73
Steve Avatar answered Sep 18 '22 11:09

Steve


In C++11 the code might invoke a move constructor to move the object rather than copy it or in both C++03 and C++11 compiler optimizations in the form of NRVO might apply copy elision to elide the copy.

Note that latter(copy elision) depends on capability of the compiler and is not guaranteed while former(Move semantics) is guaranteed in C++11.

like image 22
Alok Save Avatar answered Sep 18 '22 11:09

Alok Save