c++程序员定义的复制构造函数

需要动态分配内存的构造函数,都需要程序员自己编写复制构造函数,如果使用默认构造函数将会出现问题。

程序员可以定义一个类的复制构造函数。程序员定义的复制构造函数必须有一个形参,它是对同一个类的引用。示例原型:

  NumberArray :: NumberArray(NumberArray &obj)

  {

    arraySize = obj.arraySize;

    aPtr = new double[arraySize];

    for(int index = 0; index < arraySize; index++)

    {

      aPtr[index] = obj.aPtr[index];

    }

  }

注意:复制构造函数必须有一个形参,该形参是对同一个类的引用。如果忘记&标识符引用形参将导致编译器错误。此外,形参应该是一个const引用,因为复制构造函数不应该修改被复制的对象。

无论何时,只要在函数调用中按值传递对象,那么编译器就会自动调用复制构造函数,以创建对象的副本。正是出于这个原因,复制构造函数的形参必须按引用传递;因为,如果在构造函数被调用时按值传递,那么构造函数将立即被再次调用以创建按值传递的副本,从而导致对构造函数调用的无休止链条。

1. 复制构造函数的调用

每当创建一个对象,并使用同一个类的另一个对象来初始化它时,系统将自动调用复制构造函数,示例:

  Rectangle box(5, 10);

  Rectangle b = box;  //初始化语句

  Rectangle b1(box);   //初始化语句

当函数调用接收到某个类类型的形参时,复制构造函数也会自动调用。例如:

  void fun(Rectangle rect)

  { 

  }

假设使用以下语句来调用它: fun(fox);

这将导致Rectangle复制构造函数被调用。最后,只要函数通过值返回类的对象,就会自动调用复制构造函数。因此,在以下函数中,当return语句被执行时将调用复制构造函数:

Rectangle makeRectangle()

{

  Rectangle rect(12,3);

  return rect;

}

这是因为return 语句必须为该对象创建一个临时的非局部副本,以便在函数返回之后,调用者可以使用该副本。总而言之,一个类的复制构造函数将在以下下情况下被调用:

1)变量被使用同一个类的对象初始化。

2)函数被使用类的形参值调用。

3)函数返回的值是一个类的对象。

注意:当按引用或指针传递类的形参时,复制构造函数不会被调用。而且,当函数返回对象的引用或指针时,也不会调用复制构造函数。

  由于默认的对象赋值遇到了与默认的复制构造函数相同的问题,所有人可能会认为,程序员定义的复制构造函数也可以用来解决赋值所导致的问题,但是事实并非如此。复制构造函数仅在创建对象并初始化对象时候才起作用。特别是,复制构造函数不能在赋值中调用。要理解初始化和赋值之间的区别,可以假设已经创建了first对象,然后来看以下语句:

   NumberArray second = first;   //复制构造函数被调用

  该语句创建second对象,并使用first的值初始化它,这是一个初始化语句,她导致创建构造函数被调用来执行初始化,但是,以下语句不一样:

  second = first;   //复制构造函数未被调用

  该语句假定两个对象都是以前创建的,它仅仅是一个赋值语句,因此不会调用构造函数。

原文地址:https://www.cnblogs.com/ruigelwang/p/12626880.html