2012年2月20日 星期一

Is it a Copy Constructor or a Default Constructor and an Assignment Operator?


If you instantiate a class object x using an existing object y, such as,

Test x(y);

It is assumed that the copy constructor is called to perform the creation of the object. Further, if you use the syntax,

Test x = y;

Then, the same copy constructor is called. Is that correct, or is the default constructor called, then the assignment operator? Consider the following example.

Example 6-7a  - Copy Constructor or a Default Constructor and an Assignment Operator?

1      // File: Ex6-7a.cpp –
2      // Copy Constructor or a Default Constructor and Assignment Operator
3     
4      #include <iostream>
5      using namespace std;
6     
7      class Test
8      {
9      public:
10          Test() { cout << "default ctor: " << this << endl; }   
11          Test(const Test& arg) { cout << "copy ctor: " << this << " argument=" << &arg << endl; }   
12          Test& operator=(const Test& arg) { cout << "operator=: " << this << " argument=" << &arg << endl; return *this; }
13          Test operator+(const Test& arg) { cout << "operator+: " << this << " argument=" << &arg << endl; return *this; }
14          Test operator-(const Test& arg) { cout << "operator-: " << this << " argument=" << &arg << endl; Test temp;  return temp; }
15      };
16     
17      int main()
18      {
19          Test one;
20          Test two(one);
21          one = two;
22          Test three = one;
23          Test four = one + two;
24          Test five = one - two;
25          cout << "&five=" << &five << endl;
26     
27          return 0;
28      }


MS Visual C++ 2008

default ctor: 002BFABB                        (19)
copy ctor: 002BFAAF argument=002BFABB                    (20)
operator=: 002BFABB argument=002BFAAF                    (21)
copy ctor: 002BFAA3 argument=002BFABB                    (22)
operator+: 002BFABB argument=002BFAAF                    (23)
copy ctor: 002BFA97 argument=002BFABB                    (23)
operator-: 002BFABB argument=002BFAAF                    (24/14)
default ctor: 002BF997                        (14)
copy ctor: 002BFA8B argument=002BF997                    (24)
&five=002BFA8B                            (25)

g++ 4.4.0 on Linux

default ctor: 0x7fff43e46cff                    (19)
copy ctor: 0x7fff43e46cfe argument=0x7fff43e46cff            (20)
operator=: 0x7fff43e46cff argument=0x7fff43e46cfe            (21)
copy ctor: 0x7fff43e46cfd argument=0x7fff43e46cff            (22)
operator+: 0x7fff43e46cff argument=0x7fff43e46cfe            (23)
copy ctor: 0x7fff43e46cfc argument=0x7fff43e46cff            (23)
operator-: 0x7fff43e46cff argument=0x7fff43e46cfe            (24/14)
default ctor: 0x7fff43e46cfb                    (14)
&five=0x7fff43e46cfb                        (25)


Comments

Line 19: default constructor call
Line 20: copy constructor call
Line 21: assignment operator call
Line 22: copy constructor call.  Is this the answer to our question?  Not yet, let's look further.
Line 23: operator+ is called, then the copy constructor (same result on both compilers)
Line 24: Now here's where it gets interesting. The call to operator-() invokes a default Test constructor call in line 14. Then the MS compiler copies the temporary object using the copy constructor, since the return is "by value". The g++ compiler appears to by "optimizing this onstructor call out". So, it appear that th g++ compiler does not use the copy compiler in this case to perform the "return by value" copy.
Line 25: This illustrates that the five object was created by the copy constructor for the MS compiler and by the default constructor for the g++ compiler.

Who ever said this was going to be easy? Haven't we got better things to do with our time?

沒有留言:

張貼留言