构造、析构、赋值

时间:2022-05-28 19:31:42

 个人觉得在C++的类中,这三个函数在什么时候调用确实有点难搞清楚。下面通过一个程序的运行结果对这几个函数进行说明。
程序如下:

#include  < iostream >
using   namespace  std; 

class  Object     // 测试类
{
public :
    Object(
int  i); // 构造函数
    Object( const  Object  & other); // 复制构造函数
     const  Object &   operator = ( const  Object &  other); // 赋值函数
     ~ Object(); // 析构函数
private :
    
int  m_i;
};

Object::Object(
int  i){
    cout
<< " Object  " << i << "  constructor is called! " << endl;
    m_i
= i;
}

Object::Object(
const  Object  & other){
    cout
<< " Object copy constructor is called! " ;
    m_i
= other.m_i;
}

const  Object &  Object:: operator   = ( const  Object &  other){
    cout
<< " Object operator= is called! " ;
    
this -> m_i = other.m_i;
    
return   * this ;
}

Object::
~ Object(){
    cout
<< " Object  " << this -> m_i << "  destructor is called! " << endl;
}

Object fun(
void ){
    Object o(
2 );     // 试下把这句删去,再把return语句改为:return Object(2); 看下
     return  o;
}

int  main()
{
    cout
<< " start of main " << endl;
    Object o(
1 );
    o
= fun();         // 注意把以上两句改为:Object o=fun(); 看下结果有什么不同
    cout << " end of main " << endl;
    
return   0 ;
}

程序运行结果以下:

1.        start of main

2.        Object 1 constructor is called!

3.        Object 2 constructor is called!

4.        Object copy constructor is called!

5.        Object 2 destructor is called!

6.        Object operator= is called!

7.        Object 2 destructor is called!

8.        end of main

9.        Object 2 destructor is called!

 

 

下面逐一对结果进行分析。

 

第2句:由于Object o(1);创建了一个对象,调用了构造函数。
第3句:进入fun()后,调用构造函数创建了一个局部对象Object 2。
第4句:这里尤其要注意的是,由于fun()函数返回的是一个值类型(与Object&区分开来),故在fun()结束前,会创建一个Object 2的副本(临时对象),并且这时调用的是复制构造函数。
第5句:创建完临时对象后,上面第4句中创建的局部对象Object 2就功成身退了,调用析构函数销毁。
第6句:程序跳出fun()函数后,执行这句:“o=fun();”,由于是一个赋值操作(由于前面已对Object 1初始化,不再是调用复制构造函数),故这里会调用赋值函数。
第7句:赋值完成后,临时对象也功成身退,调用析造函数销毁。
第9句:最后析构的是main()中的Object对象。

其实上面的分析还是比较容易明白的,不过如果把main()中的Object o(1); o=fun();改为一句Object o=fun();,或者把fun()里面的程序修改一下,这下就可能令人有点糊涂了。这是因为编译器对程序进行了优化,不再是像上面一样都调用构造函数、复制构造函数,从而提高了效率。不过我觉得如果明白了上面分析的过程,就已说明你对构造、析构、赋值这三个函数有了较好的理解。