条款 12:拷贝对象的所有部分

 编译器生成的拷贝函数(拷贝构造函数,拷贝赋值运算符),会拷贝对象的所有数据,当你声明自己的拷贝函数时,就是在告诉编译器,默认实现中有你不喜欢的地方。

void logCall(const std::string& funcName); // 创造一条记录class Date { ... }; // 日期class Customer {
public:...Customer(const Customer& rhs);Customer& operator=(const Customer& rhs);...
private:std::string name;Date lastTransaction; // 后期添加的成员
};Customer::Customer(const Customer& rhs): name(rhs.name) // 拷贝rhs的数据
{logCall("Customer copy constructor");
}
Customer& Customer::operator=(const Customer& rhs)
{logCall("Customer copy assignment operator");name = rhs.name; 	// 拷贝rhs的数据return *this; 	// 见条款10
}

拷贝时,后期添加的成员被遗忘了。
出现这个问题的最狡猾的方式之一是通过继承。

class PriorityCustomer : public Customer { // 一个派生类
public:...PriorityCustomer(const PriorityCustomer& rhs);PriorityCustomer& operator=(const PriorityCustomer& rhs);
private:int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs): priority(rhs.priority){logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs){logCall("PriorityCustomer copy assignment operator");priority = rhs.priority;return *this;
}

在这里插入图片描述
在调用赋值的时候data数据由于没有进行赋值拷贝,所以在子类的赋值中缺失了该数据。
 派生类复制函数必须调用它们对应的基类函数。

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs): Customer(rhs), // 调用基类拷贝构造函数priority(rhs.priority)
{logCall("PriorityCustomer copy constructor");
}
PriorityCustomer&
PriorityCustomer::operator=(const PriorityCustomer& rhs)
{logCall("PriorityCustomer copy assignment operator");Customer::operator=(rhs); // 为基类部分赋值priority = rhs.priority;return *this;
}

在这里插入图片描述
如果没有调用的话进行赋值的时候就会导致基类部分的数据没有赋值过去。
如果两个拷贝函数有很多重复代码,可以先构造一个,再用另一个调用它吗?不要这样做!!!构造函数会初始化新对象,但赋值运算符只适用于已经初始化的对象。

  • 拷贝构造函数调用拷贝赋值运算符:对正在构造中的对象执行赋值意味着对尚未初始化的对象执行某些只对已初始化的对象有意义的操作。
  • 拷贝赋值运算符调用拷贝构造函数:将试图构造一个已经存在的对象。
  • 拷贝函数应该确保拷贝对象的所有数据成员和它的所有基类部分。
  • 不要试图用其中一个拷贝函数来实现另一个。可以将通用功能放在第三个同时调用它们的函数中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/227597.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apple Unity Plugins 接入GameCenter 崩溃解决方案

目录 问题问题原因解决方案可直接使用的UnityPlugins 问题 调用 GKLocalPlayer.Local.FetchItems() 程序崩溃,报错:Thread 1: EXC_BAD_ACCESS (code257, address0x8000000000000002) 启动崩溃,报错:Library not loaded: rpath/Ap…

【Electron】webview 实现网页内嵌

实现效果: 当在输入框内输入某个网址后并点击button按钮 , 该网址内容就展示到下面 踩到的坑:之前通过web技术实现 iframe 标签内嵌会出现 同源策略,同时尝试过 vue.config.ts 内配置跨域项 那样确实 是实现啦 但不知道如何动态切换 tagert …

sklearn学习的一个例子用pycharm jupyter

环境 运行在jupyter 进行开发。即一个WEB端的开发工具。能适时显示开发的输出。后缀用的是ipynb.pycharm也可以支持。但也要提示按装jupyter. 或直接用andcoda 这里我们用pycharm进行项目创建 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jupyterlab pip ins…

基于Python的电商手机数据可视化分析和推荐系统

1. 项目简介 本项目旨在通过Python技术栈对京东平台上的手机数据进行抓取、分析并构建一个简单的手机推荐系统。主要功能包括: 网络爬虫:从京东获取手机数据;数据分析:统计各厂商手机销售分布、市场占有率、价格区间和好评率&am…

Java进阶(第八期): Java中递归的的使用和递归解决一些算法问题 Java中的异常机制、异常的处理逻辑 自定义异常

文章目录 一、递归1.1 递归的介绍1.2 递归的简单练习1.3 图解递归执行流程:1.4 使用递归完成悲波那契数列1.5 猴子吃桃子问题 二、异常三 、异常的处理逻辑3.1 try catch 捕获异常3.2 throws抛出异常 四、自定义异常 Java进阶(第八期) 一、递…

科技云报道:开源才是大模型的未来?

科技云报道原创。 一年前,ChatGPT横空出世;7个多月后,Meta宣布开源LLaMA 2,并且可免费商用。 这一天,也成为大模型发展的分水岭。短时间内,LLaMA 2对一些闭源的大模型厂商造成了致命性的打击。 随后&…

SpringMVC源码解析——DispatcherServlet初始化

在Spring中,ContextLoaderListener只是辅助功能,用于创建WebApplicationContext类型的实例,而真正的逻辑实现其实是在DispatcherServlet中进行的,DispatcherServlet是实现Servlet接口的实现类。Servlet是一个JAVA编写的程序&#…

HBase 超大表迁移、备份、还原、同步演练手册:全量快照 + 实时同步(Snapshot + Replication)不停机迁移方案

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

自动化测试系列 之 Python单元测试框架unittest

一、概述 什么是单元测试 单元测试是一种软件测试方法,是测试最小的可测试单元,通常是一个函数或一个方法。 在软件开发过程中,单元测试作为一项重要的测试方法被广泛应用。 为什么需要单元测试 单元测试是软件开发中重要的一环&#xf…

TG7050CKN,TG7050SKN ,TG7050CMN,TG7050SMN

爱普生推出的温补晶振型号:TG7050CKN,TG7050SKN ,TG7050CMN,TG7050SMN频率范围为 10mhz ~ 54mhz 适用于广泛的频率需求。这几款的特点就是耐高温,温度可达105℃高温,而且都是高稳定性温补晶振,&…

21 UVM printer

uvm_printer 类提供了以不同格式打印 uvm_objects 的灵活性。我们已经讨论了使用 uvm_field_* 宏的 print() 方法,或者如果不使用 utils_begin/ end 宏,则编写 do_print() 方法。 UVM printer提供四种内置printer。 uvm_printeruvm_table_printeruvm_t…

键盘字符(#键)显示错误

当屏幕上显示的键与键盘上按下的键不同时,尤其是 # 键。大多数情况下,此错误是由于 raspbian 和 NOOBS 软件的默认英国键盘配置所致。 解决方案: 要解决此问题,您需要将配置更改为您自己的键盘或语言的配置。这可以通过转到树莓派…

EasyCVR无人机推流+人数统计AI算法,助力公共场所人群密度管控

一、背景与需求 在公共场所和大型活动的管理中,人数统计和人群密度控制是非常重要的安全问题。传统的方法可能存在效率低下或准确度不足的情况,无法满足现代社会的需求。TSINGSEE青犀可以利用无人机推流AI人流量统计算法,基于计算机视觉技术…

项目实战--Message Queue

一. 概念篇 我们在学习多线程的时候,学习过生产者-消费者模型,为了实现解耦合和削峰填谷,引入了阻塞队列. 在实际的后端开发中,跨主机之间使用生产者消费者模型,也是非常普遍的需求,因此,阻塞队列会被封装成一个独立的服务器程序,实现更丰富的功能.这样的程序称为"消息队列…

Spark编程实验四:Spark Streaming编程

目录 一、目的与要求 二、实验内容 三、实验步骤 1、利用Spark Streaming对三种类型的基本数据源的数据进行处理 2、利用Spark Streaming对Kafka高级数据源的数据进行处理 3、完成DStream的两种有状态转换操作 4、把DStream的数据输出保存到文本文件或MySQL数据库中 四…

MFC - 给系统菜单(About Dialog)发消息

文章目录 MFC - 给系统菜单(About Dialog)发消息概述笔记resource.h菜单的建立菜单项的处理MSDN上关于系统菜单项值的说法END MFC - 给系统菜单(About Dialog)发消息 概述 做了一个对话框程序, 在系统菜单(在程序上面的标题栏右击)中有"关于"的菜单. 这个是程序框架…

【数据结构】八、查找

一、基本概念 静态查找:只查找,不改变集合内数据元素 动态查找:有则输出元素,无则添加元素 二、静态查找表 2.1顺序查找 在线性表、链表、树中依次查找 2.2折半查找(二分查找) 在有序的线性表中&…

基于轻量级GhostNet模型开发构建生活场景下生活垃圾图像识别系统

轻量级识别模型在我们前面的博文中已经有过很多实践了,感兴趣的话可以自行移步阅读: 《移动端轻量级模型开发谁更胜一筹,efficientnet、mobilenetv2、mobilenetv3、ghostnet、mnasnet、shufflenetv2驾驶危险行为识别模型对比开发测试》 《基…

【Java JVM】Java 实例对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。 但是 reference 类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用, 并没有定义这个引用应该通过什么方式去定位, 访问到堆中对象的具体位置, 所以对象访问方式也是由虚拟机实现而定的,主流…

深入探索小红书笔记详情API:解锁内容创新的无尽潜力

一、引言 在当今信息爆炸的时代,内容创新已经成为品牌和个人脱颖而出的关键。小红书,作为全球最大的消费类口碑库之一,每天产生大量的用户生成内容。而小红书笔记详情API,作为一个强大的工具,能够为内容创作者提供深入…