rockstone

上善若水,水利万物而不争

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

看这段很简单的代码:

代码
class A
{
public:
    A()
    {
        cout 
<< "A";
    }
    A(
const A& a)
    {
        cout 
<< "C";
    }
    A &
operator = (const A& a)
    {
        cout 
<< "B";
        
return *this;
    }
    
~A()
    {
        cout 
<< __FUNCTION__;
    }
};

A fun(A a)
{
    
return a;
}

A fun1(
const A& a)
{
    
return a;
}

A
& fun2(A& a)
{
    
return a;
}


int _tmain(int argc, _TCHAR* argv[])
{
    A a1;
    A a2 
= fun1(a1);
    cout 
<< endl;
  return 0;
}

 情况1:

main函数中执行:

A a1;
A a2 = fun(a1);
cout 
<< endl;

return 0;

程序输出为:

ACCA::~A
A::~AA::~A

解释:

1.首先创建一个对象a1,调用构造函数会输出A。

2.然后调用fun()函数,由于fun函数是按值传递参数,所以会创建一个a1的拷贝,即临时对象,我们把这个拷贝命名为copy1,调用拷贝构造函数输出C。

3.由于fun函数的返回值类型是类A,所以在return的时候,会创建返回值的一个拷贝copy2,所以又会调用拷贝构造函数输出C。

4.fun函数执行完成后,临时对象copy1被销毁,调用析构函数输出A::~A。

5.执行a2=fun(a1)的等号时,不会调用拷贝构造函数,而是把copy2赋给a2,a2就相当于无名对象copy2的名字。

6.main函数执行完,按顺序析构a2,a1,输出A::~AA::~A。

 

情况2:

main函数中执行:

 A a1;
 fun(a1);
 cout << endl;

输出为:

ACCA::~A
A::~AA::~A

解释:和情况1中不同的只是fun返回的对象没有用到,copy2就立即被析构,在输出回车之前输出A::~A。

 

情况3:

 A a1;
 A a2 = fun1(a1);
 cout << endl;

输出为:

AC
A::~AA::~A

解释:fun1传递的是引用,所以传递参数时不会创建临时对象进行拷贝,所以只在返回的时候输出一个C。

 

情况4:

 A a1;
 fun1(a1);
 cout << endl;

输出为:

ACA::~A
A::~A

不解释,上文有。

 

情况5:

 A a1;
 A a2 = fun2(a1);
 cout << endl;

输出为:

AC
A::~AA::~A

解释:注意与情况3的区别,尽管输出是一样的,当执行过程不一样。fun2参数传递的是引用,返回的也是引用,所以在执行fun2过程中都不会进行对象拷贝。fun2执行完后返回,在执行a2 = fun2(a1)创建对象a2时会调用拷贝构造函数,输出C。

 

情况6:

 A a1;
 fun2(a1);
 cout << endl;

输出为:

A
A::~A

不解释。

 

情况7:

 A a1;
 A a2 = a1;
 cout << endl;

输出:

AC
A::~AA::~A

解释:A a2 = a1;创建a2时是通过调用拷贝构造函数创建而不是重载的=函数。

 

情况8:

A a1;
A a2;

a2 = a1; 

cout << endl;

输出为:

AAB
A::~AA::~A

解释:a2已经创建,执行a2=a1进行赋值,会调用重载的=操作符,而不是拷贝构造函数,所以输出B。

posted on 2010-02-24 22:43  rockstone  阅读(678)  评论(0编辑  收藏  举报