• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

带你粗略了解C++中的深浅拷贝

c++ 搞代码 4年前 (2022-01-06) 92次浏览 已收录 0个评论
文章目录[隐藏]

这篇文章主要给大家介绍了关于c++中深浅拷贝以及写时拷贝实现的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧

一. 背景

首先看这样一个问题,在Car类中聚合了Engine类

二. 代码实现

下面给出类Car与类Engine的定义

Car.h

 #ifndef COPY__CAR_H_ #define COPY__CAR_H_ #include "Engine.h" #include  using namespace std; class Car { public: // 构造函数 Car(); Car(string brand, int version); ~Car(); // 添加或者修改一个引擎 void setEngine(string engine_brand, int engine_version); // 对汽车信息进行描述 string description() const; private: string brand; // 品牌 int version; // 型号 Engine *engine; // 引擎 }; #endif //COPY__CAR_H_ 

Car.cpp

 #include "Car.h" #include  Car::Car() { this->brand = "无"; this->version = 0; this->engine = nullptr; } Car::Car(string brand, int version) { engine = nullptr; this->brand = brand; this->version = version; } Car::~Car() { } void Car::setEngine(string engine_brand, int engine_version) { if (engine) { delete engine; } engine = new Engine(engine_brand, engine_version); } string Car::description() const { stringstream result; result << "品牌:" << brand << " 版本:" << version <description(); return result.str(); } 

Engine.h

 #ifndef COPY__ENGINE_H_ #define COPY__ENGINE_H_ #includ<mark style="color:transparent">来源gaodaimacom搞#^代%!码网</mark>e  using namespace std; class Engine { public: Engine(); Engine(string brand, int version); ~Engine(); string description() const; private: string brand; int version; }; #endif //COPY__ENGINE_H_ 

Engine.cpp

 #include "Engine.h" #include  Engine::Engine() { this->brand = "无"; this->version = 0; } Engine::Engine(string brand, int version) { this->brand = brand; this->version = version; } Engine::~Engine() { } string Engine::description() const { stringstream result; result << " 发动机品牌:" << brand << " 发动机版本:" << version; return result.str(); } 

在大部分情况下,在类中不去实现拷贝构造函数是可行的,C++编译器会帮助我们自动生成一个拷贝构造函数. 并且这个拷贝构造函数足以应对很多问题,但是当遇到指针的时候情况变得不同.下面给一个示例代码:

 #include "Car.h" #include  using namespace std; int main() { // 创建car_1对象 Car car_1("宝马", 1); // 为car_1对象添加一个引擎 car_1.setEngine("宝马", 1); // 创建car_2对象, 并且拷贝自car_1 Car car_2(car_1); // 输出修改引擎前的两个对象信息 cout << car_1.description() << endl; cout << car_2.description() << endl; // 修改引擎 car_2.setEngine("奔驰", 1); // 输出修改引擎以后的两个对象信息 cout << car_1.description() << endl; cout << car_2.description() << endl; return 0; } 

三. 问题

当我们对car_2对象的引擎进行修改时, 我们所期望的结果是仅仅只有car_2对象的引擎被修改,可是事实如此吗?

结果显示,并不是这样,car_1对象的引擎和car_2对象的引擎都被改变了.

原因就是C++编译器帮我们合成的拷贝构造函数是一个浅拷贝,只是将变量的值拷贝过来,在Car类中的成员变量engine是一个指针变量,存放的是一个地址.在进行拷贝构造时,就意味着car_1对象中engine变量和car_2对象中的engine变量存放的是同一个地址值(由于是new出来的对象, 所以地址engine变量中存放的值处于堆空间). 如图所示.(地址是瞎编的)

四. 解决方法

解决方法就是:手动实现拷贝构造函数,实现深拷贝,如图所示.

在Car.cpp文件中添加如下代码 :

 Car::Car(const Car &other) { this->brand = other.brand; this->version = other.version; engine = new Engine(other.brand, other.version); } 

主函数不变,得到如下结果:

总结

以上就是带你粗略了解C++中的深浅拷贝的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:带你粗略了解C++中的深浅拷贝

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址