Part6 数组指针与字符串 6.12 对象复制与移动

Posted LeoSirius

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Part6 数组指针与字符串 6.12 对象复制与移动相关的知识,希望对你有一定的参考价值。

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;
}

 

以上是关于Part6 数组指针与字符串 6.12 对象复制与移动的主要内容,如果未能解决你的问题,请参考以下文章

Part6 数组指针与字符串 6.13字符串

Part6 数组指针与字符串 6.2 数组作为函数的参数 6.3对象数组 6.4基于范围的for循环

Part6 数组指针与字符串 6.6指针与数组

Part6 数组指针与字符串 6.1 数组的定义与初始化

面向对象 part6 继承

C++对象数组与对象指针