热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅析C++中的深浅拷贝

原标题:浅析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++中的深浅拷贝


推荐阅读
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Python如何调用类里面的方法
    本文介绍了在Python中调用同一个类中的方法需要加上self参数,并且规范写法要求每个函数的第一个参数都为self。同时还介绍了如何调用另一个类中的方法。详细内容请阅读剩余部分。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了一个程序,可以输出1000内能被3整除且个位数为6的所有整数。程序使用了循环和条件判断语句来筛选符合条件的整数,并将其输出。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
author-avatar
墮天使love蘇蘇_709
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有