• 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;   //复制构造函数未被调用

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

  • 相关阅读:
    2020软件工程作业05
    2020软件工程作业00--问题清单
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    软件工程个人作业06
    软件工程作业04
    软件工程作业05
    软件工称作业03
    2020软件工程作业02
  • 原文地址:https://www.cnblogs.com/ruigelwang/p/12626880.html
Copyright © 2020-2023  润新知