作者:墮天使love蘇蘇_709 | 来源:互联网 | 2023-05-30 17:15
原标题:浅析C++中的深浅拷贝一. 背景 首先看这样一个问题,在Car类中聚合了Engine类二. 代码实现 下面给出类Car与类Engine的定义Car.h#ifndef COPY__CAR_H_#
原标题:浅析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 <<"品牌:" <description();www.yii666.com
return result.str();
}
Engine.h
#ifndef COPY__ENGINE_H_
#define COPY__ENGINE_H_
#include
using namespace std;
class Engine {
public:
Engine();
Engine(string brand, int version);
~Engine();
string description() const;
private:
string brand;
int v文章来源地址49492.htmlersion;
};
#endif //COPY__ENGINE_H_
Engine.cpp
#include "Engine.h"
#include
Engine::Ewww.yii666.comngine() {
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 <<" 发动机品牌:" < 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 < cout < // 修改引擎
car_2.setEngine("奔驰", 1);
// 输出修改引擎以后的两个对象信息
cout < cout < return 0;
}
三. 问题
当我们对car_2对象的引擎进行修改时, 我们所期望的结果是仅仅只有car_2对象的引擎被修改,可是事实如此吗?
结果文章来源站点https://www.yii666.com/显示,并不是这样,car_1对象的引擎和car_2对象的引擎都被改变了.
原因就是C++编译器帮我们合成的拷贝构造函数是一个浅拷贝,只是将变量的值拷贝过来,在Car类中的成员变量engine是一个指针变量,存放的是一个地址.在进行拷贝构造时,就意味着car_1对象中engine变量和car_2对象中的engine变量存放的是同一个地址值(由于是new出来的对象, 所以地址engine变量中存放的值处于堆空间). 如图所示.(地址是瞎编的)
四. 解决方法
解决方法就是:手动实现拷贝构造函数,实现深拷贝,如图所示.
在Car.cpp文件中添加如下代码:
Car::Car(const Car &文章来源地址49492.html;other) {
this->brand = other.brand;
this->version = other.version;
engine = new Engine(other.brand, other.version);
}
主函数不变,得到如下结果:
来源于:浅析C++中的深浅拷贝