c++深拷贝与浅拷贝
来源:互联网 发布:qq晒米软件 编辑:程序博客网 时间:2024/05/17 06:34
类的聚集:
类的成员中含有某个类的指针,就叫做类的聚集。对象中只存放数据的地址,数据可以是数组或者对象等。
浅拷贝:
对象之间的元素一一复制,这就是拷贝构造函数的本能。当数据成员是指针时,就会出现问题!
深拷贝:
被复制的对象数据成员是指针类型时,不会复制指针成员本身,而是将指针所指向的对象进行复制!
浅拷贝demo
#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
#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;}
不再使用默认的拷贝构造函数,因为派生类成员含有指针,因此逐个拷贝所指向的数据,从而正确完成拷贝,称之为“深拷贝“。
执行结果如下:
0 0
- c++-深拷贝与浅拷贝
- 【c++】浅拷贝与深拷贝
- Objective-C 深拷贝与浅拷贝
- [C++]深拷贝与浅拷贝
- C语言拾遗:位拷贝与值拷贝,浅拷贝与深拷贝
- C语言拾遗:位拷贝与值拷贝,浅拷贝与深拷贝
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- “浅拷贝”与“深拷贝”
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- 浅拷贝与深拷贝
- 深拷贝与浅拷贝
- 深拷贝与浅拷贝
- “浅拷贝”与“深拷贝”
- 深拷贝与浅拷贝
- java中的&与&&
- 黑马程序员-java基础-内部类
- eclipse在centos下面崩溃
- 使用maven的profile和filter插件管理配置项
- sun.misc.BASE64Encoder在Eclipse中不能直接使用的原因和解决方案
- c++深拷贝与浅拷贝
- halcon学习之仿射变换1
- Android, 随时随地退出程序ActivityCollector
- UISlider的简单使用,一年不用一次,我是真怕自己忘了怎么用
- 对多线程对订单更新竞争的锁机制的实现-初构
- Seafile服务器配置
- 建立第一个窗体
- 机器人书单与学习资源——导航篇
- 51nod 1428 活动安排问题