1. 在声明语句中用一个对象初始化另一个对象;

2. 将一个对象作为参数按值调用方式传递给另一个对象时生成对象副本;

3. 生成一个临时对象作为函数的返回结果。

那么接着就看一下在这三种情况下拷贝构造函数分别在什么时候调用,以及如果有临时对象的话,在什么时候析构。先假定有一个类FOO,在构造函数中会输出“Constructing.”,在拷贝构造函数中会输出“Copy constructing.”,在析构函数中会输出“Destructing.”。输出结果中的注释是说明之用。

在声明语句中用一个对象初始化另一个对象

在声明语句中用一个对象初始化另一个对象时,不存在临时对象的问题,新的对象直接调用拷贝构造函数,进行对象的初始化,也没有什么调用顺序的问题了,例如:

程序代码:

  • FOO obj1;
  • FOO obj2=obj1;

如果类FOO有拷贝构造函数,那么在定义时就会调用拷贝构造函数,在对象的生存周期结束时,调用对象的析构函数。上面这段程序的输出结果就是:

程序代码:

  • Constructing.    // constructing obj1
  • Copy constructing.    // constructing obj2
  • Destructing.    // destructing obj2
  • Destructing.    // destructing obj2

将一个对象作为参数按值调用方式传递给另一个对象时生成对象副本

将对象按值调用作为函数的参数时,在函数的开始将生成一个临时对象,如果对象有拷贝构造函数,就使用拷贝构造函数对临时对象进行初始化,然后在函数结事调用临时对象的析构函数,例如:

程序代码:

  • void get_object(pobj) {
  •     FOO obj;
  •     return;
  • }

在上面这段代码中,先执行的是参数pobj的初始化,然后再进行局部对象变量obj的初始化。以上代码输出结果如下:

程序代码:

  • Copy constructing.    // copy constructing pobj
  • Constructing.    // constructing obj
  • Destructing.    // destructing obj
  • Destructing.    // destructing pobj

生成一个临时对象作为函数的返回结果

生成一个临时对象作为函数的返回结果时,如果返回结果有拷贝构造函数就会调用返回结果的拷贝构造函数进行初始化,而且是在return语句执行时进行,并且在return完成时调用析构函数,例如:

程序代码:

  • FOO get_object() {
  •     FOO obj;
  •     return obj;
  • }
  • FOO myobj;
  • myobj=get_object();

在函数get_object()内部,先进行obj的初始化,在执行到return语句时,创建一个临时对象,调用拷贝构造函数用obj作为参数对临时对象进行初始化,而之后则是先进行函数内部对象变量的析构,再进行临时变量的析构,因为临时变量要在函数外部对可能接收返回值的变量进行赋值。以上代码的输出结果如下:

程序代码:

  • Constructing.    // constructing myobj
  • Constructing.    // constructing obj
  • Copy constructing.    // copy constructing temp obj
  • Destructing.    // destructing obj
  • Destructing.    // destructing temp obj
  • Destructing.    // destructing myobj

就这样,在VC调试了3个例子就可以差不多弄清拷贝构造函数的调用时间了。