- 复制构造
- 复制构造函数被调用的三种情况
- 深层复制?">为什么需要深层复制?
- 疑惑
复制构造
复制构造函数被调用的三种情况
1、定义一个对象时,以本类另一个对象作为初始值,发生复制构造;
2、如果函数的形参是类的对象,调用函数时,将使用实参对象初始化形参对象,发生复制构造;
3、如果函数的返回值是类的对象,函数执行完成返回主调函数时,将使用return语句中的对象初始化一个临时无名对象,传递给主调函数,此时发生复制构造。
如:
- 通过使用另一个同类型的对象来初始化新创建的对象。 ```cpp Point a(10,20);
Point b=a;
//分析:将对象a赋给参数p,即右边是p.x=a.p,左边x的x,y是b的xy分量(this->x=p.x)
- 复制对象把它作为参数传递给函数。```cppvoid fun1(Point p){cout<<p.get(X)<<endl;}//调用语句:fun1(b);
复制对象,并从函数返回这个对象。 ```cpp Point fun2(){
return Point(1,2);
}
//调用语句: b=fun2();
<a name="QR6yT"></a>### 浅层复制实现对象间数据元素的一一对应复制。<a name="rNptv"></a>### 深层复制当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针(或引用)所指对象进行复制。 <br />实现深层copy的方法,就是在类中手动而外添加copy构造函数,如下:```cpp类名::类(const 类名&对象名)//复制构造函数的实现{函数体}
代码如:
class A {public:A() {m = new int[4]{ 1,2,3,4 };std::cout << "constructor" << std::endl;}~A() {if (m != nullptr) {delete[] m;}}A(const A& a) {this->m = new int[4];memcpy(a.m, this->m, this->len * sizeof(int));std::cout << "copy constructor" << std::endl;}// 移动构造A(A&& a) : m(a.m) {a.m = nullptr;std::cout << "move constructor" << std::endl;}// 赋值操作符重载A& operator= (const A& a) {memcpy(a.m, this->m, this->len * sizeof(int));std::cout << "operator" << std::endl;return *this;}private:int len = 4;int* m = nullptr;};A getA(A a) {return a;}int main(void){A a; // constructA b = a; // copy constructA c(a); // copy constructA d; // constructd = a; // operateA e = getA(a); // construct, move constructreturn 0;}
为什么需要深层复制?
先看一个例子
#include <iostream>#include <cassert>using namespace std;class Point {public:Point() : x(0), y(0) {cout<<"Default Constructor called."<<endl;}Point(int x, int y) : x(x), y(y) {cout<< "Constructor called."<<endl;}~Point() { cout<<"Destructor called."<<endl; }int getX() const { return x; }int getY() const { return y; }void move(int newX, int newY) {x = newX;y = newY;}private:int x, y;};class ArrayOfPoints {//动态数组类public:ArrayOfPoints(int size) : size(size) {points = new Point[size];}~ArrayOfPoints() {cout << "Deleting..." << endl;delete[] points;}Point& element(int index) {assert(index >= 0 && index < size);return points[index];}private:Point *points; //指向动态数组首地址int size; //数组大小};int main() {int count;cout << "Please enter the count of points: ";cin >> count;ArrayOfPoints pointsArray1(count); //创建对象数组pointsArray1.element(0).move(5,10);pointsArray1.element(1).move(15,20);ArrayOfPoints pointsArray2(pointsArray1); //创建副本cout << "Copy of pointsArray1:" << endl;cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", "<< pointsArray2.element(0).getY() << endl;cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", "<< pointsArray2.element(1).getY() << endl;pointsArray1.element(0).move(25, 30);pointsArray1.element(1).move(35, 40);cout<<"After the moving of pointsArray1:"<<endl;cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", "<< pointsArray2.element(0).getY() << endl;cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", "<< pointsArray2.element(1).getY() << endl;return 0;}
运行代码出现了错误,是因为复制的对象虚构函数执行两次,第一次已经析构了,对象已经不存在,再次析构编译器就会不知道析构对象是什么,报错。
所以需要而外添加复制构造函数,添加代码如下:
ArrayOfPoints::ArrayOfPoints(const ArrayOfPoints& v) {size = v.size;points = new Point[size];for (int i = 0; i < size; i++)points[i] = v.points[i];}
疑惑
本人测试,新的编译器会自动帮我们完成深copy,不报错
class Test {public:Test(int* p) { p = p; };int* p;//Test (const Test &obj) {// p = new int();// p = obj.p;// cout << "复制构造" << endl;//}~Test() {delete p;}};int main(){// cout<<[](int x, int y) {return x + y; }(2, 5);auto sum= [](int x, int y) {return x + y; };//cout<<sum(1, 2);int a = 10;int*b = &a;Test myt(b);Test myt2 = myt;//写法copy1Test myt3(myt);//写法copy2}
拷贝构造函数:https://www.runoob.com/cplusplus/cpp-copy-constructor.html
