Skip to content

Latest commit

 

History

History
90 lines (59 loc) · 2.85 KB

File metadata and controls

90 lines (59 loc) · 2.85 KB

第14讲 复制构造函数

注意这里的「复制」不是动词。本节 Java 用户需要特别注意。
视频地址:https://www.coursera.org/learn/cpp-chengxu-sheji/lecture/P1ssX/fu-zhi-gou-zao-han-shu

基本概念

  • 只有一个参数:即对同类对象的引用。

    形如

      X::X(X&);
      // or 
      X::X(const X&);
  • 如果没有定义复制构造函数,则编译器会生成默认复制构造函数,完成复制功能。 假定有一个类 Complex,它使用默认构造函数:

    class Complex {
      double real;
      double imag;
      public:
          ......
    };

    下面的调用方式将使用复制构造函数:

    Complex c1;     // 调用默认无参构造函数
    Complex c2(c1); // 调用复制构造函数,将 c2 初始化成和 c1 一样

    和默认构造函数类似,如果自定了复制构造函数,则编译器不再生成默认的构造函数。自定义的复制构造函数甚至可以不做复制的工作,虽然这可能是一种不好的实践。

  • 不允许有形如 X::X(X) 的构造函数

    class Nono {
      Nono(Nono n); // !错,不允许定义这种形式的构造函数
    };

    这个限制虽然 Java 没有,但如果在编写 Java 类中这样写,仍然是不好的实践。

复制构造函数的作用

  • 用一个对象去初始化同类的另一个对象。

    Complex c2(c1);
    Complex c2 = c1; // !这是一条初始化语句,并非赋值语句!

    以上两条语句是等价的,都是用对象 c1 去初始化对象 c2。特别需要注意第二句,它不是赋值语句。它和下面的语句并不等价:

    Complex c2;
    c2 = c1;

    注意!!! 惯用 Java 的话,这里几乎肯定会是一个坑。

  • 如果某函数有一个参数类A的对象,那么该函数被调用时,类A的复制构造函数会被调用。

    ``` C++ class A { public: A(){}; // 这里这个无参构造函数也必须写上,否则 A a 不能正常生成对象 A(A &a); };

A::A(A &a) { cout << "Copy constructor called." << endl; }

//空函数 void func(A a) { // 参数类型是 A. }

int main() { A a; func(a); // 输出 "Copy constructor called." return 0; }

``` (代码下载)

  • 如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数会被调用。

视频中的随堂问题很有意思:
pic
原因如前面所述。

为什么需要复制构造函数?

TO BE CONTINUED...


<Previous | Home | Next>