C++ 入门06:类的进阶(构造函数的重载与拷贝构造函数)

往期回顾:

C++ 入门03:函数与作用域-CSDN博客
C++ 入门04:数组与字符串-CSDN博客
C++ 入门05:类和对象-CSDN博客


一、前言

在前面文章的学习中,我们了解了 C++ 的基本结构、变量、输入输出、控制结构、循环、函数、作用域、数组与字符串以及类和对象的基础知识。今天,我们将深入学习类的进阶内容,特别是构造函数的重载与拷贝构造函数。

二、类的进阶

2.1、 构造函数的重载

(1)什么是构造函数重载

构造函数的重载是面向对象编程中一个非常有用的特性,它允许在同一个类中定义多个构造函数,这些构造函数具有相同的名称(即与类名相同)但参数列表不同。参数列表的不同可以体现在参数的数量、类型或顺序上。这种设计允许开发者根据不同的初始化需求,以灵活的方式创建对象实例。

(2)为什么需要构造函数的重载?

  1. 提高代码灵活性
    构造函数的重载提供了一种灵活的方式来初始化对象。不同的构造函数可以处理不同的初始化场景,从而避免在单个构造函数中使用复杂的逻辑判断来决定如何根据提供的参数初始化对象。例如,一个Person类可能提供多个构造函数,一个接受名字和年龄,另一个只接受名字,还有一个无参构造函数用于创建默认状态的Person对象。

  2. 增强代码可读性
    通过为不同的初始化场景提供明确的构造函数,可以使得代码更加清晰易懂。调用者可以根据需要直接选择合适的构造函数来创建对象,而无需担心构造函数内部的复杂逻辑。

  3. 支持多种初始化方式
    在某些情况下,对象的初始化可能依赖于外部数据源或配置文件的内容。通过重载构造函数,可以设计不同的构造函数来接受不同的数据源或配置方式,从而使得类的使用更加灵活和通用。

  4. 提高类的可重用性
    通过重载构造函数,可以使得类更容易被其他类继承和使用。子类可以根据需要覆盖或扩展父类的构造函数,以提供额外的初始化逻辑或支持新的初始化场景。

  5. 符合设计原则
    构造函数的重载也符合面向对象设计中的一些基本原则,如单一职责原则和开闭原则。单一职责原则要求一个类只负责一件事情,通过重载构造函数,我们可以将初始化对象的不同方式分散到不同的构造函数中,从而使得每个构造函数都专注于一种特定的初始化场景。开闭原则则要求软件实体对扩展开放,对修改关闭。通过重载构造函数,我们可以在不修改现有代码的情况下添加新的初始化方式,从而符合开闭原则的要求。

示例:

#include <iostream>
using namespace std;class Car {
public:string brand;string model;int year;// 默认构造函数Car() {brand = "Unknown";model = "Unknown";year = 0;}// 带参数的构造函数Car(string b, string m, int y) {brand = b;model = m;year = y;}// 只提供品牌和年份的构造函数Car(string b, int y) {brand = b;model = "Unknown";year = y;}void displayInfo() {cout << "Brand: " << brand << endl;cout << "Model: " << model << endl;cout << "Year: " << year << endl;}
};int main() {Car car1; // 调用默认构造函数Car car2("Toyota", "Corolla", 2020); // 调用带参数的构造函数Car car3("Honda", 2018); // 调用只提供品牌和年份的构造函数car1.displayInfo();car2.displayInfo();car3.displayInfo();return 0;
}

在这个示例中,我们定义了三个构造函数:

默认构造函数:不接受任何参数,初始化所有属性为默认值。

带参数的构造函数:接受品牌、型号和年份参数。
只接受品牌和年份的构造函数:型号设置为默认值 "Unknown"。

2.2.、拷贝构造函数 

(1)什么是拷贝构造函数 

 拷贝构造函数是C++中一个非常关键的特殊成员函数,它的主要作用是创建并初始化一个新对象,该新对象是通过复制另一个已存在的同类型对象(源对象)来完成的。这个复制过程不仅仅是简单地复制对象中的每个字节,而是根据对象的类型和实际需求来执行更加复杂的操作。

拷贝构造函数的名字与类名相同,但它接受一个指向该类型对象的常量引用作为参数。这个参数是源对象的引用,用于从源对象复制数据到新对象中。由于参数是常量引用,因此拷贝构造函数不会修改源对象。

class MyClass {  
public:  // ... 其他成员 ...  // 拷贝构造函数  MyClass(const MyClass& other) {  // 复制操作  }  
};

(2)为什么需要拷贝构造函数?

  1. 动态内存管理
    当类的对象包含指向动态分配内存的指针时,默认的拷贝构造函数只会复制指针的值,而不会复制指针所指向的内存区域。这会导致两个对象共享同一块内存区域,从而引发内存泄漏或双重释放等问题。通过自定义拷贝构造函数,我们可以确保每个对象都拥有自己独立的内存区域,避免这些问题。

  2. 深拷贝与浅拷贝
    拷贝构造函数允许我们实现深拷贝或浅拷贝。深拷贝意味着除了复制对象的值之外,还复制了对象内部所有动态分配的内存或其他资源。浅拷贝则只复制了对象的值,而没有复制其内部资源。根据对象的特性和需求,我们可以选择实现深拷贝或浅拷贝。

  3. 资源管理
    除了动态内存之外,对象还可能管理其他类型的资源,如文件句柄、网络连接等。通过自定义拷贝构造函数,我们可以确保这些资源在对象复制时得到正确的管理,例如为每个新对象分配新的资源实例或共享资源(但通常不推荐共享资源,因为它可能引入复杂的同步和并发问题)。

  4. 性能优化
    在某些情况下,我们可能希望优化对象的复制过程以提高性能。通过自定义拷贝构造函数,我们可以实现更高效的复制策略,例如使用移动语义(在C++11及更高版本中通过移动构造函数和移动赋值运算符实现)来避免不必要的复制操作。

  5. 符合设计原则
    自定义拷贝构造函数使得类的行为更加清晰和可预测。它允许类的设计者精确地控制对象复制时的行为,从而符合面向对象设计中的一些基本原则,如封装性、一致性和可维护性。

示例:

#include <iostream>
using namespace std;class Car {
public:string brand;string model;int year;// 带参数的构造函数Car(string b, string m, int y) {brand = b;model = m;year = y;}// 拷贝构造函数Car(const Car &oldCar) {brand = oldCar.brand;model = oldCar.model;year = oldCar.year;}void displayInfo() {cout << "Brand: " << brand << endl;cout << "Model: " << model << endl;cout << "Year: " << year << endl;}
};int main() {Car car1("Toyota", "Corolla", 2020);Car car2 = car1; // 使用拷贝构造函数car1.displayInfo();car2.displayInfo();return 0;
}

在这个示例中,我们定义了一个拷贝构造函数,它接受一个 Car 类的对象作为参数,并复制其属性值。这样,car2 对象就是通过复制 car1 对象来初始化的。


以上就是 C++ 程序的构造函数的重载与拷贝构造函数的基本用法的知识点了。通过构造函数的重载,我们可以用不同的方式初始化对象,而拷贝构造函数使我们能够复制对象并执行额外的操作。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

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

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

相关文章

windows USB 设备驱动开发-USB电源管理(一)

符合通用串行总线 (USB) 规范的 USB 设备的电源管理功能具有一组丰富而复杂的电源管理功能。 请务必了解这些功能如何与 Windows 驱动程序模型 (WDM) 交互&#xff0c;特别是 Microsoft Windows 如何调整标准 USB 功能以支持系统唤醒体系结构。 基于内核模式驱动程序框架的 US…

图像到文本的桥梁:Transformer模型的创新应用

图像到文本的桥梁&#xff1a;Transformer模型的创新应用 在人工智能领域&#xff0c;Transformer模型以其卓越的性能在自然语言处理&#xff08;NLP&#xff09;任务中占据了重要地位。然而&#xff0c;Transformer的潜力并不局限于文本&#xff0c;它在图像到文本转换&#…

2024年06月CCF-GESP编程能力等级认证Python编程四级真题解析

本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级,那他可以选择的认证语言有几种?( ) A. 1 B. 2 C…

React文档内网搭建

React文档内网搭建流程 官网地址 官网中文地址 通过官网我们可以找到React的github存储库 ReactGitHub 在介绍中可以找到对应的文档存储库 React文档存储库 此存储库是英文文档地址,我们通过中文文档地址以及该存储库作者目录下找到中文存储库 React文档中文存储库 下载…

VIM三种模式的操作

目录 1. 普通模式 1.1 复制粘贴 1.2 移动光标 1.3 撤回 1.4 删除 2. 编辑模式 3. 命令模式 3.1 保存并退出 3.2 强制执行 3.3 显示/取消行号 3.4 搜索文本 3.5 取消高亮 3.6 全局替换 1. 普通模式 1.1 复制粘贴 &#xff08;1&#xff09;鼠标选中双击&am…

13个Python自动化实战脚本

1、批量文件重命名神器在工作中&#xff0c;我们常常需要对大量文件进行批量重命名&#xff0c;Python帮你轻松搞定&#xff01; 2、自动发送邮件通知告别手动发送&#xff0c;用Python编写定时发送邮件的自动化脚本。 3、定时任务自动化执行使用Python调度库&#xff0c;实现定…

高盛开源的量化金融 Python 库

GS Quant GS Quant是用于量化金融的Python工具包&#xff0c;建立在世界上最强大的风险转移平台之一之上。旨在加速量化交易策略和风险管理解决方案的开发&#xff0c;凭借25年的全球市场经验精心打造。 它由高盛的定量开发人员&#xff08;定量&#xff09;创建和维护&#…

2024.7.10刷题记录

目录 一、1001-[NOIP2007]字符串的展开 二、1003-[NOIP2010]机器翻译 三、853. 有边数限制的最短路 - AcWing题库 bellman_ford算法 四、851. spfa求最短路 - AcWing题库 spfa算法 一、1001-[NOIP2007]字符串的展开 p1, p2, p3 map(int, input().split()) st input() n…

qt 读写json格式的配置文件

要点 QJsonObject QJsonDocumentQFile file(fileName);file.write(jsonDoc.toJson(QJsonDocument::Indented)); // 缩进格式化输出QByteArray jsonData file.readAll(); 在 Qt 中&#xff0c;读写 JSON 格式的配置文件通常使用 QJsonDocument、QJsonObject、QJsonArray 和 Q…

云开发技术的壁纸小程序源码,无需服务期无需域名

1、本款小程序为云开发版本&#xff0c;不需要服务器域名 2、文件内有图文搭建教程&#xff0c;小白也不用担心不会搭建。 3、本程序反应速度极快&#xff0c;拥有用户投稿、积分系统帮助各位老板更多盈利。 4、独家动态壁纸在线下载&#xff0c;给用户更多的选择 5、最新版套图…

Open3D 点云配准精度评价指标-RMSE

目录 一、概述 1.1RMSE的计算方法 1.2RMSE的评价标准 二、代码实现 三、实现效果 3.1原始点云 3.2计算数据 一、概述 均方根误差(RMSE, Root Mean Squared Error)是衡量两个点云之间平均误差的一个常用指标。它通过计算匹配点对之间距离的平方和的平方根,来…

有必要找第三方软件测评公司吗?如何选择靠谱软件测评机构?

软件测试是确保软件质量的重要环节&#xff0c;而在进行软件测试时&#xff0c;是否有必要找第三方软件测评公司呢?第三方软件测评公司是指独立于软件开发公司和用户之间的中立机构&#xff0c;专门从事软件测试和测评工作。与自身开发团队或内部测试团队相比&#xff0c;选择…

计算机的错误计算(二十七)

摘要 介绍错数&#xff1a;任给一个单变元函数&#xff0c;当自变量被截断时&#xff0c;函数值中含有的错误的有效数字个数&#xff0c;并给出其计算方法。 首先&#xff0c;从字面上看&#xff0c;错数表示错误的有效数字个数。 下面从一个略显粗糙的化简过程&#xff0c;推…

每天一个数据分析题(四百二十)- 一元线性回归模型

现在通过参数估计得到一个一元线性回归模型为y 3x4&#xff0c;在回归系数检验中下列说法错误的是&#xff08; &#xff09; A. 检验统计量是t统计量 B. 原假设是β13 C. 若拒绝原假设&#xff0c;就认为自变量与因变量存在显著的线性关系 D. 可以用P值与显著性水平比较结…

网络安全防御【防火墙安全策略用户认证综合实验】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤 1、打开ensp防火墙的web服务&#xff08;带内管理的工作模式&#xff09; 2、在FW1的web网页中网络相关配置 3、交换机LSW6&#xff08;总公司&#xff09;的相关配置&#xff1a; 4、路由器相关接口配置&a…

多线程问题

什么是线程 线程是cpu调度和执行的单位&#xff0c;一个程序的运行伴随着的是一个进程的执行&#xff0c;而一个进程是由一个或多个线程来完成的&#xff0c;通过cpu调度资源在很短时间切换主线程和子线程并行&#xff0c;交替执行来做到看似多个线程同时进行的状态&#xff0…

java入门-告别C进入java世界

目标 java体系 java开发环境 helloworld java语法 java体系 java开发环境 安装JDK JDK&#xff1a; Java Developement Kit 配置jdk 为什么需要配置 操作系统找不到此程序 操作系统PATH PATH C:\Users\49354>echo %PATH% C:\Program Files (x86)\VMware\VMware Works…

windows信息收集和提权

目录 手动收集 工具收集 windows本地内核提权 本地提权 根据windows去找需要的exp进行利用 提权后结合mimikatz使用 msf提权 简单提权 生成后门 上线 BypassUAC绕过UAC提权 msf带的bypassuac模块可以尝试提权 Bypassuac提权命令操作 提权成功 ​local_exploi…

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:841)

pip安装python库时报错问题解决 报错&#xff1a;[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:841) 解决&#xff1a; pip --trusted-host pypi.python.org install -r packagename&#xff08;包名&#xff09;

C# IOC容器、依赖注入和控制反转

控制反转&#xff08;Inversion of Control, IoC&#xff09; 定义&#xff1a;控制反转是一种设计原则&#xff0c;它反转了传统编程中的控制流程。在传统的编程模式中&#xff0c;组件之间的依赖关系是由组件自身在内部创建和维护的。而在控制反转模式中&#xff0c;这种依赖…