0

Possible Duplicate:
Why copy constructor is not called in this case?

In the following code, I constructed three variables, a1, a2 and a3.

There's a example in C++ Primer p.476:

string empty_copy = string();//copy-initialization

Is there anyone can help me explain

1)why a1 and a2 are not constructed by copy constructor and

2)what's the difference between initialization a2 in my code and empty_copy in the book?

Thanks so much!

#include<iostream>
using namespace std;
class A{
public:
    A(){}
    A(int v){}
    A(const A&x){
        cout<<"copy constructor"<<endl;
    }
};
A generateA(){
    return A(0);
}
int main(){
        cout<<"First:"<<endl;
        A a1=generateA();

        cout<<"Second:"<<endl;
        A a2=A(0);

        cout<<"Third:"<<endl;
        A a3=a1;
    return 0;
}

The out put is (under Visual Studio 2010 in Win7 and g++ in Ubuntu10.10):

First:
Second:
Third:
copy constructor
Community
  • 1
  • 1
P.H
  • 5
  • 2

3 Answers3

6

This is copy elision due to Return value optimization.
Compilers are allowed to optimze away generation of copies by applying such optimizations.

A a1=generateA(); 
A a2=A(0); 

In the above both cases the compiler can eliminate the creation of a temporary object which is created to hold the return value.

A a3=a1;

Involves a already existing named object a1 which is used for construction of a3 this involves a copy constructor call which the compiler must make and cannot optimize.

EDIT: To answer the Q in comment.

You can tell the compiler to not apply this optimization by using the following options during compilation:

For GCC:

-fno-elide-constructors

For MVSC:

/Od
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1
  1. The copy constructor is not used in for a1 and a2 because in both cases you are passing an int and therefore the compiler is using the A(int) constructor you've defined.

  2. The difference between yours and the example from the book, is that the book is creating an instance on the stack (string()), and therefore getting an empty-copy, whilst in your case, you are using an existing instance (a1). Both are using the copy constructor for initialisation.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
1

When you initializa a1, you have an integer argument (given in your factory function). For a2 you also pass an integer. For a3 you say that a3=a1. This is interpreted as a3(a1) as you have a copy constructor defined, and so it is called.

learnvst
  • 15,455
  • 16
  • 74
  • 121