个人觉得在C++的类中,这三个函数在什么时候调用确实有点难搞清楚。下面通过一个程序的运行结果对这几个函数进行说明。
程序如下:
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()里面的程序修改一下,这下就可能令人有点糊涂了。这是因为编译器对程序进行了优化,不再是像上面一样都调用构造函数、复制构造函数,从而提高了效率。不过我觉得如果明白了上面分析的过程,就已说明你对构造、析构、赋值这三个函数有了较好的理解。