IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 浅析C++中的深浅拷贝 -> 正文阅读

[C++知识库]浅析C++中的深浅拷贝

一. 背景

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

二. 代码实现

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

Car.h


#ifndef COPY__CAR_H_
#define COPY__CAR_H_
#include "Engine.h"
#include <string>

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 <sstream>

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 << engine->description();
  return result.str();
}

Engine.h

#ifndef COPY__ENGINE_H_
#define COPY__ENGINE_H_
#include <string>

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 <sstream>

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 <iostream>

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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 11:52:27  更:2021-08-19 11:52:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 11:51:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码