1 深层复制与浅层复制
浅层复制:实现对象间数据元素的一一对应复制。
深层复制:当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指对象进行复制。
//6-22 对象的深层复制 #include <iostream> #include <cassert> using namespace std;//Point同6-18 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(const ArrayOfPoints& pointsArray);//新加的复制构造函数 ~ArrayOfPoints(){ cout << "Deleting..." << endl; delete[] points; } Point& element(int index){//element函数来取数组的元素 assert(index >= 0 && index < size);//下标不能越界 return points[index];//返回引用可以用来操作封装数组对象内部的数组元素,返回值则不能 } private: Point *points;//指向动态数组首地址 int size; }; ArrayOfPoints::ArrayOfPoints(const ArrayOfPoints& v){//新加的复制构造函数,实现深层复制 size = v.size; points = new Point[size]; for(int i = 0; i < size; i++) points[i] = v.points[i]; } 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; }
2 移动构造
C++11 标准中提供了一种新的构造方法——移动构造。
C++11 引入移动语义:
源对象资源的控制权全部交给目标对象
当临时对象在被复制后,就不再被利用了。我们完全可以把临时对象的资源直接移动,这样就避免了多余的复制操作。
//1 使用深层复制构造函数 #include<iostream> using namespace std; class IntNum{ public: IntNum(int x = 0):xptr(new int(x)){//构造函数 cout << "Calling constructor..." << endl; } IntNum(const IntNum &n):xptr(new int(*n.xptr)){//复制构造函数(.优先级高于*) cout << "Calling copy constructor..." << endl; } ~IntNum(){//析构函数 delete xptr; cout << "Destructing..." << endl; } int getInt(){return *xptr;} private: int *xptr; }; IntNum getNum(){//返回值为IntNum类对象 IntNum a; return a;//返回时调用复制构造,构造一个临时无名对象给主函数,a自己被析构 } int main(){ cout << getNum().getInt() << endl;//这里析构临时无名对象 return 0; }
//2 使用移动构造函数 #include<iostream> using namespace std; class IntNum{ public: IntNum(int x = 0):xptr(new int(x)){ cout << "Calling constructor..." << endl; } IntNum(const IntNum &n):xptr(new int(*n.xptr)){ cout << "Calling copy constructor..." << endl; } IntNum(IntNum &&n):xptr(n.xptr){//移动构造函数,用参数对象成员的指针初始化当前成员的指针 n.xptr = nullptr;//这样析构函数delete空指针,不会发生多次析构 cout << "Calling move constructor..." << endl; } ~IntNum(){ delete xptr; cout << "Destructing..." << endl; } int getInt(){return *xptr;} private: int *xptr; }; IntNum getNum(){ IntNum a; return a; } int main(){ cout << getNum().getInt() << endl; return 0; }