您的位置:首页 > 编程语言 > C语言/C++

c++深拷贝与浅拷贝

2015-09-14 21:07 549 查看

类的聚集:

[code]类的成员中含有某个类的指针,就叫做类的聚集。
对象中只存放数据的地址,数据可以是数组或者对象等。


浅拷贝:

对象之间的元素一一复制,这就是拷贝构造函数的本能。当数据成员是指针时,就会出现问题!

深拷贝:

被复制的对象数据成员是指针类型时,不会复制指针成员本身,而是将指针所指向的对象进行复制!

浅拷贝demo

[code]#include <iostream>

using namespace std;

class Basic {
public:
    Basic() {
        cout << "default Basic() run" << endl;
    }
    Basic(int x, int y) {
        this->x = x;
        this->y = y;
        cout << "Basic(int x, int y) run" << endl;
    }
    ~Basic() {
        cout << "de-constructor ~Basic() run" << endl;
    }
    int GetX() { return this->x; }
    int GetY() { return this->y; }

    void Assign(int x, int y) {
        this->x = x; 
        this->y = y;
    }
private:
    int x, y;
};

class low_copy_Basic : public Basic {
public:
    low_copy_Basic(int length) {
        this->numberOfBasic = length; 
        this->pointer = new Basic[length];
    }
    ~low_copy_Basic() {
        cout << "~low_copy_Basic() run..." << endl;
        this->numberOfBasic = 0;
        delete[] this->pointer;
    }
    Basic &GetElement(int length) {
        return this->pointer[length];
    }

private:
    Basic *pointer;
    int numberOfBasic;
};

int main(void)
{
    // Assign
    low_copy_Basic obj_1 = low_copy_Basic(2);
    obj_1.GetElement(0).Assign(1, 2);
    obj_1.GetElement(1).Assign(3, 4);

    low_copy_Basic obj_2 = low_copy_Basic(obj_1);
    cout << "obj_2" << endl;
    cout << obj_2.GetElement(0).GetX() << " and " << obj_2.GetElement(0).GetY() << endl;
    cout << obj_2.GetElement(1).GetX() << " and " << obj_2.GetElement(1).GetY() << endl;

    // change
    obj_2.GetElement(0).Assign(5, 6);
    obj_2.GetElement(1).Assign(7, 8);
    cout << "after change, obj_1 :" << endl;
    cout << obj_1.GetElement(0).GetX() << " and " << obj_1.GetElement(0).GetY() << endl;
    cout << obj_1.GetElement(1).GetY() << " and " << obj_1.GetElement(1).GetY() << endl;

    return EXIT_SUCCESS;
}


Basic类有x y 两个数据成员,其派生类low_copy_Basic有Basic * 和长度计数。

注意,派生类我使用的是默认的拷贝构造函数,因此它执行浅拷贝,仅仅拷贝成员对应的元素本身,这也是运行后出现错误的根源!因为派生类对象obj_1和obj_2指向了同一个内存区域pointer!析构函数delete了两次!

运行结果:



深拷贝demo

[code]#include <iostream>

using namespace std;

class Basic {
public:
    Basic() {
        cout << "default Basic() run" << endl;
    }
    Basic(const int x, const int y) {
        this->x = x;
        this->y = y;
        cout << "Basic(int x, int y) run" << endl;
    }
    ~Basic() {
        cout << "de-constructor ~Basic() run" << endl;
    }
    int GetX() { return this->x; }
    int GetY() { return this->y; }

    void Assign(const int x, const int y) {
        this->x = x; 
        this->y = y;
    }
private:
    int x, y;
};

class low_copy_Basic : public Basic {
public:
    low_copy_Basic() {
        this->numberOfBasic = 0; 
        this->pointer = nullptr;
    }
    low_copy_Basic(int length) {
        this->numberOfBasic = length; 
        this->pointer = new Basic[length];
    }
    ~low_copy_Basic() {
        cout << "~low_copy_Basic() run..." << endl;
        this->numberOfBasic = 0;
        delete[] this->pointer;
    }

    low_copy_Basic(const low_copy_Basic &rhs);

    Basic &GetElement(int length) {
        return this->pointer[length];
    }

private:
    Basic *pointer;
    int numberOfBasic;
};

low_copy_Basic::low_copy_Basic(const low_copy_Basic &rhs) {
    int current_length = rhs.numberOfBasic;
    this->pointer = new Basic[current_length];
    for (int i = 0; i < current_length; ++i)
        this->pointer[i].Assign(rhs.pointer[i].GetX(), rhs.pointer[i].GetY());
}

int main(void)
{
    // Assign
    low_copy_Basic obj_1 = low_copy_Basic(2);
    obj_1.GetElement(0).Assign(1, 2);
    obj_1.GetElement(1).Assign(3, 4);

    low_copy_Basic obj_2 = low_copy_Basic(obj_1);
    cout << "obj_2" << endl;
    cout << obj_2.GetElement(0).GetX() << " and " << obj_2.GetElement(0).GetY() << endl;
    cout << obj_2.GetElement(1).GetX() << " and " << obj_2.GetElement(1).GetY() << endl;

    // change
    obj_2.GetElement(0).Assign(5, 6);
    obj_2.GetElement(1).Assign(7, 8);
    cout << "after change, obj_1 :" << endl;
    cout << obj_2.GetElement(0).GetX() << " and " << obj_1.GetElement(0).GetY() << endl;
    cout << obj_2.GetElement(1).GetX() << " and " << obj_1.GetElement(1).GetY() << endl;

    return EXIT_SUCCESS;
}


不再使用默认的拷贝构造函数,因为派生类成员含有指针,因此逐个拷贝所指向的数据,从而正确完成拷贝,称之为“深拷贝“

执行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: