本教程将通过示例解释拷贝构造函数,以及它们的用途和如何在 C++ 中复制对象。
拷贝构造函数是一种特殊的构造函数,主要用于创建现有类的对象的副本。具体来说,它将现有对象的成员变量值复制到新对象的成员变量中。
拷贝构造函数的通用函数原型如下:
ClassName (const ClassName &old;_obj);
以下是定义和调用拷贝构造函数的语法:
//Definition
ClassName objectName (ClassName &existingObject;)
{
Var1 = existingObject.Var1;
Var2 = existingObject.Va2;
}
//Calling
ClassName ob1;
ClassName ob2(&ob1;);
让我们通过一个例子来理解语法:
#include <iostream>
using namespace std;
class Transport
{
public:
int wheels;
string name;
string type;
string color;
Transport(int n)
{
wheels=n;
}
Transport(Transport &ob;) // a copy constructor is Defined
{
wheels=ob.wheels;
}
};
int main()
{
Transport bike1(2); // 1st constructor is Called
Transport bike2(bike1); //Method1 is calling a copy constructor
Transport bike3=bike2; //Method2 is calling a copy constructor
cout<<"bike2 has "<<bike2.wheels<<" wheels \n";
cout<<"bike3 has "<<bike3.wheels<<" wheels";
输出
bike2 has 2 wheels bike3 has 2 wheels
在以下情况下可能会调用 C++ 中的拷贝构造函数:
然而,不能保证在所有这些情况下都会调用拷贝构造函数,因为 C++ 标准允许编译器在某些情况下(例如返回值优化,即 RVO)消除复制。
返回值优化 (RVO):这是一种 C++ 编程语言中使用的编译器优化,用于消除存储函数返回值的临时对象。C++ 标准允许 RVO 改变生成程序的可见行为。
可以将拷贝构造函数设置为私有。当我们将类中的拷贝构造函数设置为私有时,该类中的所有对象都将无法复制。当我们的类包含指针或动态分配的资源(例如文件句柄、网络连接等)时,这非常有用。
拷贝省略是 C++ 计算机编程中使用的一种编译器优化技术,它将防止未使用的对象复制。
在拷贝省略中,编译器会阻止创建不必要的或额外的副本,这既节省了空间,又将改善程序的复杂性(包括时间和空间)。因此,代码看起来更高效。
通常,C++ 语言标准允许实现使用任何优化,只要结果程序的可见行为与程序完全按照标准要求执行时的行为相同即可。除此之外,标准还概述了一些即使这样做可能会改变程序行为,也可以避免复制的情况。返回值优化就是最典型的例子。
例如,让我们编写一个 C++ 程序来理解 C++ 中拷贝省略的工作原理?
#include <iostream>
using namespace std;
class LeT {
public:
void print() { cout << " Hai and hello friends!"; }
};
int main()
{
LeT L;
for (int i = 0; i <= 2; i++) {
L.print();
}
return 0;
}
输出
Hai and hello friends! Hai and hello friends! Hai and hello friends!
编译器现在必须选择打印什么;它可能会选择打印上面显示的结果或下面显示的两种情况之一。这被称为返回值优化。简单来说,返回值优化(RVO)是一种方法,它让编译器对终止生成的临时对象拥有更多控制权,从而影响最终程序的可见行为和属性。
情况 1
嗨,朋友们好!
嗨,朋友们好!
情况 2
嗨,朋友们好!
对于每个类,如果我们不定义自己的拷贝构造函数,C++ 编译器会提供一个默认的拷贝构造函数,它在对象之间执行成员式复制。编译器生成的拷贝构造函数通常表现良好。如果对象具有指针或任何其他运行时资源分配(例如文件句柄、网络连接等),那么我们才需要定义自己的拷贝构造函数。
默认构造函数只执行浅拷贝。

只有用户定义的拷贝构造函数才允许深拷贝。我们确保复制对象的指针(或引用)在用户定义的拷贝构造函数中指向新的内存位置。
