C++中什么时候调用复制构造函数?

C++中什么时候调用复制构造函数?

C++中,复制构造函数(Copy Constructor)被用于创建一个新的对象,该对象是使用另一个对象作为参数,或通过另一个对象进行初始化得到的。该复制构造函数必须接受另一个对象的引用作为参数,否则它将不能正确地工作。复制构造函数还可以从派生类向基类进行类型转换。

下面,让我们看一些情况,它们触发了C++中复制构造函数的调用。

拷贝初始化

当使用一个对象来初始化另一个对象时,通常会调用复制构造函数。例如:

#include <iostream>

using namespace std;

class Rectangle {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(const Rectangle& rec) {
         width = rec.width;
         height = rec.height;
         cout << "Copy constructor called" << endl;
      }
};

int main() {
   Rectangle rec1(10, 20);
   Rectangle rec2 = rec1;   // copy constructor called
   Rectangle rec3(rec1);   // copy constructor called
   return 0;
}

在上面的示例中,创建了一个名为rec1的Rectangle对象,这个对象的宽度是10,高度是20。然后,通过拷贝初始化方法,创建了另外两个Rectangle对象:rec2rec3。在这里,复制构造函数被调用了两次,用于初始化rec2rec3

以值返回对象

当函数将一个对象作为返回值传递给它的调用者时,也会调用复制构造函数。

#include <iostream>

using namespace std;

class Rectangle {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(const Rectangle& rec) {
         width = rec.width;
         height = rec.height;
         cout << "Copy constructor called" << endl;
      }
};

Rectangle duplicate(Rectangle& rec) {
   Rectangle duplicate_rec(rec.width, rec.height);
   // do some modifications to the new object
   return duplicate_rec;  // copy constructor called
}

int main() {
   Rectangle rec1(10, 20);
   Rectangle rec2 = duplicate(rec1);
   return 0;
}

在上面的示例中,duplicate()函数将一个Rectangle对象作为参数,并创建一个新的Rectangle对象,该对象是通过以rec.widthrec.height初始化得到的。然后,函数执行一些修改,最终返回这个新的对象。在这里,复制构造函数被调用了一次,用于将新的对象返回给调用者。

通过一个对象初始化另一个对象

当一个对象通过另一个对象进行初始化时,也会调用复制构造函数。例如:

#include <iostream>

using namespace std;

class Rectangle {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(const Rectangle& rec) {
         width = rec.width;
         height = rec.height;
         cout << "Copy constructor called" << endl;
      }
};

int main() {
   Rectangle rec1(10, 20);
   Rectangle rec2(rec1);
   return 0;
}

在上面的示例中,创建了一个名为rec1Rectangle对象。然后,通过另一个Rectangle对象rec2,用rec1初始化了它。在这里,复制构造函数被调用了一次,用于初始化rec2

数组赋值

当数组被赋值给另一个数组时,每个元素都将使用其对应的复制构造函数进行复制。例如:

#include <iostream>

using namespace std;

class Rectangle {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(constRectangle& rec) {
         width = rec.width;
         height = rec.height;
         cout << "Copy constructor called" << endl;
      }
};

int main() {
   Rectangle rec1(10, 20);
   Rectangle rec2(5, 5);
   Rectangle arr[] = {rec1, rec2};
   Rectangle arr_copy[2];
   arr_copy[0] = arr[0];   // copy constructor called
   arr_copy[1] = arr[1];   // copy constructor called
   return 0;
}

在上面的示例中,创建了两个Rectangle对象:rec1rec2。然后,这两个对象被存储在一个数组arr中。接下来,又创建了一个新数组arr_copy,并将arr的元素赋值给它。在这里,复制构造函数被调用了两次,用于复制arr中的元素。

参数传递

当一个对象通过引用传递给函数时,该函数可能会调用复制构造函数。例如:

#include <iostream>

using namespace std;

class Rectangle {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(const Rectangle& rec) {
         width = rec.width;
         height = rec.height;
         cout << "Copy constructor called" << endl;
      }
};

void modify(Rectangle& rec) {
   // do some modifications to the object
}

int main() {
   Rectangle rec1(10, 20);
   modify(rec1);   // copy constructor called
   return 0;
}

在上面的示例中,rec1对象通过引用传递给modify()函数。在这里,当rec1被传递给函数时,复制构造函数被调用了一次。

基类和派生类

在C++中,一个派生类的对象可以隐式地转换为一个基类的对象。这个转换可能会调用复制构造函数。例如:

#include <iostream>

using namespace std;

class Shape {
   public:
      int x, y;
};

class Rectangle: public Shape {
   public:
      int width, height;
      Rectangle(int w, int h) {
         width = w;
         height = h;
      }
      Rectangle(const Rectangle& rec) {
         width = rec.width;
         height = rec.height;
         x = rec.x;
         y = rec.y;
         cout << "Copy constructor called" << endl;
      }
};

int main() {
   Rectangle rec(10, 20);
   Shape shape = rec;   // copy constructor called
   return 0;
}

在上面的示例中,创建了一个名为recRectangle对象,它的宽度为10,高度为20。然后,通过派生类Rectangle,隐式地将它转换为基类Shape的对象。在这里,复制构造函数被调用了一次,用于将rec转换为shape

结论

在C++中,复制构造函数在以下情况下会被调用:

  • 对象通过拷贝初始化方式创建。
  • 对象通过一个对象初始化另一个对象。
  • 从函数以值的方式返回一个对象。
  • 数组赋值。
  • 通过引用传递对象给函数。
  • 派生类的对象隐式转换为基类的对象。

在理解这些场景后,我们可以更好地使用C++中的复制构造函数来优化我们的代码。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程