1.复制指针所指的对象
#include <iostream> #include <vector> #include <string> #include <cstdlib> #include "stdio.h" #include <cassert> using namespace std; class Point { private: int a, b; public: Point():a(0),b(0){ cout << "Default call" << endl; return ; } Point(int x, int y) : a(x), b(y){ cout << "Constructor called." << endl; } ~Point(){ cout << "Destructor called." << endl; } int getX() const { return this->a; } int gety() const { return this->b; } void move(int nX, int nY){ a = nX; b = nY; } }; class ArrayPoint { private: Point *po; //指向动态数组首地址 int size;//数组大小 public: //自己写一个复制构造函数, 作为深层复制 ArrayPoint(ArrayPoint &v); ArrayPoint(int num):size(num){ //size 初始值设置 cout << "Construct ArrayPoint." << endl; po = new Point[size];//在构造函数中分配内存 } ~ArrayPoint(){ cout << "Destruct ArrayPoint." << endl; delete[] po; //在析构函数中释放内存 } Point& element(int index) //返回是应用类型,element是Point类型 { assert(index >= 0 && index <= size);//判断下标是否越界 return po[index];//返回下标为index的数组 } }; ArrayPoint::ArrayPoint(ArrayPoint &v) //深层复制 { size = v.size;//参数v的size赋值 po = new Point[size]; //赋以指针值 for (int i = 0; i < size; i++) //将参数数组里面的每一个值一一赋值给当前数组对象 { po[i] = v.po[i]; } } int main() { cout << "------------5-------------" << endl; //动态数组类 //写一个ArrayPoint类 ArrayPoint kk(5); //关键用法,创建数组对象 kk.element(0).move(5,10); // 访问数组元素的成员 kk.element(1).move(15,20); ArrayPoint k_2(kk); //创建副本,目的是想将kk的内容全部复制给k_2 cout << "Copy of kk:" << endl; cout << "k_2 of array:" << k_2.element(0).getX()<<", "<<k_2.element(0).gety() << endl; cout << "k_2 of array:" << k_2.element(1).getX()<<", "<<k_2.element(1).gety() << endl; cout << "After the moving of kk:" << endl; //把kk数组的元素移动一下,看看k_2数组是否会变化,若无变化,则表示复制成功 kk.element(0).move(100,200); // 访问数组元素的成员 kk.element(1).move(300,400); cout << "k_2 of array:" << k_2.element(0).getX()<<", "<<k_2.element(0).gety() << endl; cout << "k_2 of array:" << k_2.element(1).getX()<<", "<<k_2.element(1).gety() << endl; return 0; }原理图
过程:size的值从kk复制到k_2, 然而po的值,并没有复制给k_2。 而是在k_2中构造了一个同样大的数组,将kk数组对象的每一个数复制到k_2数组对象中,这就达到了深层复制的效果。
思想:比如说把钱从一个账号转到另一个账号;将电脑的文件从一个路径剪切到另一个路径;移动的过程只是让对象换了换地方,并没有发生复制。
C++11标准中提供了一种新的构造方法——移动构造C++ 11之前,如果要将源目标对象的状态转移到目标对象只能通过复制。在某些情况下,我们没有必要复制对象——只需要移动他们C++11引入移动语义:源对象资源的控制权全部交给目标对象
左边是复制构造:当一个对象需要进行复制构造的时候,首先要复制出相同大小的内存空间单元,在对象被复制以后,临时对象和a对象各自占用堆内存,堆内存大小相同。也就是完成出一个副本
右边是移动:而移动是让临时对象原本控制的内存空间,转移给对象a。如果临时对象不用了,那么就可以移选择移动构造,相比于复制构造,移动构造不需要建立一个新的内存。
class_name(class_name &&)