C++11 新特性:继承构造函数

C++11 标准引入了继承构造函数(Inheriting Constructors),这是对 C++ 类继承机制的一个重要补充。

在这之前,派生类不能直接使用基类的构造函数来初始化其对象,这导致了,在某些情况下需要在派生类中重复基类构造函数的代码,增加了代码的冗余。继承构造函数特性的引入,旨在减少这种冗余,提高代码的复用性。

提出背景

在 C++11 之前,如果基类有多个构造函数,派生类需要为自己需要用到的每一个基类构造函数编写对应的构造函数,即使这些派生类构造函数只是简单地将参数传递给基类构造函数。

这不仅增加了代码量,也提高了维护成本,因为任何基类构造函数的修改,都需要在所有派生类中进行相应的更新。

继承构造函数允许派生类继承基类的所有构造函数,从而无需在派生类中显式定义这些构造函数。这样做可以显著减少代码重复,使得派生类的编写更加简洁明了。

此外,这还意味着基类构造函数的任何修改都会自动反映在派生类中,无需手动更新派生类代码,从而降低了维护成本。

基本用法

假设有一个基类 Base,它有多个构造函数:


class Base {
public:Base() {// 默认构造函数的实现}Base(int value) {// 带参数的构造函数实现}
};

在 C++11 之前,如果想在派生类Derived中使用这些构造函数,需要显式定义它们:

class Derived : public Base {
public:Derived() : Base() {// 派生类使用基类的默认构造函数}Derived(int value) : Base(value) {// 派生类使用基类的带参数构造函数}
};

而使用C++11的继承构造函数特性,可以简化为:

class Derived : public Base {using Base::Base; // 继承基类的所有构造函数
};

在这个示例中,通过在派生类中使用 using Base::Base; 语句,Derived 类自动继承了 Base 类的所有构造函数。不需要在 Derived 类中显式定义这些构造函数,就可以像使用 Base 类的构造函数那样使用它们来初始化 Derived 类的对象。

这里使用了 using 关键字,通常情况下,using 声明语句只是令某个名字在当前作用域内可见。**而当作用于构造函数时,using 声明语句将令编译器产生代码。**对于基类的每个构造函数,编译器都生成一个与之对应的派生类构造函数。换句话说,对于基类的每个构造函数,编译器都在派生类中生成一个形参列表完全相同的构造函数。

这些编译器生成的构造函数形如:

Derived(parms) : Base(args) { }

其中,Derived 是派生类的名字,Base 是基类的名字,parms 是构造函数的形参列表,args 将派生类构造函数的形参传递给基类的构造函数。

在我们的 Derived 类示例中,继承的构造函数等价于:

Derived() : Base() { }
Derived(int value) : Base(value) { }

如果派生类含有自己的数据成员,则这些成员将被默认初始化。

继承构造函数与多重继承

如果从多个基类中继承了相同的构造函数(即形参列表完全相同),则程序将产生错误:

struct Base1{Base1() = default;Base1(const std::string&);Base1(std::shared ptr<int>);
};struct Base2 {Base2() = default;Base2(const std::string&);Base2(int);
};// 错误: D1 试图从两个基类中都继承D1::D1(const string&)
struct D1 : public Base1, public Base2
{using Base1::Base1; //从 Base1 继承构造函数using Base2::Base2; //从 Base2 继承构造函数
};

如果一个类从它的多个基类中继承了相同的构造函数,则这个类必须为该构造函数定义它自己的版本:

struct D2:public Base1, public Base2 {using Base1::Basel; //从 Base1 继承构造函数using Base2::Base2; //从 Base2 继承构造函数// D2 必须自定义一个接受 string 的构造函数D2(const string &s) : Base1(s), Base2(s) { }D2()= default; // 一旦 D2 定义了它自己的构造函数,则必须出现
};

继承构造函数的特点

1、和普通成员的 using 声明不一样,一个构造函数的 using 声明不会改变该构造函数的访问级别。

例如,不管 using 声明出现在哪儿,基类的私有构造函数在派生类中还是一个私有构造函数;受保护的构造函数和公有构造函数也是同样的规则。

而且,一个 using 声明语句不能指定 explicit 或 constexpr。如果基类的构造函数是 explicit 或者 constexpr,则继承的构造函数也拥有相同的属性。

2、当一个基类构造函数含有默认实参时,这些实参并不会被继承。相反,派生类将获得多个继承的构造函数,其中每个构造函数分别省略掉一个含有默认实参的形参。

例如,如果基类有一个接受两个形参的构造函数,其中第二个形参含有默认实参,则派生类将获得两个构造函数:

  • 一个构造函数接受两个形参(没有默认实参);

  • 另一个构造函数只接受一个形参,它对应于基类中最左侧的没有默认值的那个形参。

3、如果基类含有几个构造函数,则除了两个例外情况,大多数时候派生类会继承所有这些构造函数。

第一个例外是,派生类可以继承一部分构造函数,而为其他构造函数定义自己的版本。

如果派生类定义的构造函数,与基类的构造函数具有相同的参数列表,则该构造函数将不会被继承。定义在派生类中的构造函数将替换继承而来的构造函数。

第二个例外是默认、拷贝和移动构造函数不会被继承。这些构造函数按照正常规则被合成。继承的构造函数不会被作为用户定义的构造函数来使用,因此,如果一个类只含有继承的构造函数,则它也将拥有一个合成的默认构造函数。

总结

C++11 中引入的继承构造函数特性极大地简化了派生类的编写,通过允许派生类自动继承基类的构造函数,减少了代码的重复和维护成本。

这提高了代码的复用性和可维护性,使得基于类的继承更加灵活和强大。继承构造函数强化了C++作为一种面向对象编程语言的能力,使得开发者可以更加专注于设计的逻辑,而不是重复的代码实现。

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

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

相关文章

python笔记基础--用户输入和while循环(4)

目录 一.用户输入 1.函数input( ) 1.1用户输入 1.2数值输入int( ) 1.3求模运算符% 二.循环while 1.使用while循环 2.退出 2.1让用户选择何时退出 2.2使用标志 2.3 break退出循环 2.4 continue 2.5避免无限循环 3.使用while循环处理列表和字典 3.1在列表之间移动…

Day42:WEB攻防-PHP应用MYSQL架构SQL注入跨库查询文件读写权限操作

目录 PHP-MYSQL-Web组成架构 PHP-MYSQL-SQL常规查询 手工注入 PHP-MYSQL-SQL跨库查询 跨库注入 PHP-MYSQL-SQL文件读写 知识点&#xff1a; 1、PHP-MYSQL-SQL注入-常规查询 2、PHP-MYSQL-SQL注入-跨库查询 3、PHP-MYSQL-SQL注入-文件读写 MYSQL注入&#xff1a;&#xff…

什么是PLC物联网关?PLC物联网关有哪些功能?

在数字化浪潮的推动下&#xff0c;工业物联网&#xff08;IIoT&#xff09;正逐步成为推动制造业智能化转型的关键力量。而在这一变革中&#xff0c;PLC物联网关扮演着至关重要的角色。今天&#xff0c;就让我们一起走进PLC物联网关的世界&#xff0c;了解它的定义、功能&#…

5.3.1、【AI技术新纪元:Spring AI解码】OpenAI 图像生成

OpenAI 图像生成 OpenAI 图像生成前提条件自动配置图像生成属性连接属性重试属性运行时选项OpenAI 图像生成 Spring AI 支持 OpenAI 的图像生成模型 DALL-E。 前提条件 要访问 ChatGPT 模型,您需要创建一个 OpenAI 的 API 密钥。首先在 OpenAI 注册页面创建一个账户,并在 …

python使用pandas根据sheet名称读取内容,并转化为字典

要使用pandas读取指定sheet的内容并将其转化为字典&#xff0c;你需要先安装pandas库&#xff08;如果尚未安装的话&#xff09;&#xff0c;然后按照以下步骤操作&#xff1a; 导入pandas库。使用pandas的read_excel函数读取Excel文件。通过to_dict方法将DataFrame转化为字典…

计算机组成原理 例题集

补码的规格化表示是小数点后一位与符号位不同&#xff1a;数符为0,这个数就是正数,正数补码就是其本身,其最高有效位(阶码使用标准移码的话规格化后尾数最高有效位就是小数点后第一位)必定为1,数符0和最高有效位的1相异.数符为1,这个数就是个负数,求负数的补码有一步叫按位取反…

在服务器(Ubuntu20.04)安装用户级别的cuda11.8(以及仿照前面教程安装cuda11.3后安装cudnn和pytorch1.9.0)

1、cuda11.8的下载 首先在cuda官网下载我们需要的cuda版本&#xff0c;这里我下载的是cuda11.8&#xff08;我的最高支持cuda12.0&#xff09; 这里我直接使用wget命令下载不了&#xff0c;于是我直接在浏览器输入后面的链接下载到本地&#xff0c;之后再上传至服务器的&am…

Springboot+vue的四川美食分享网站+数据库+报告+免费远程调试

项目介绍: Springbootvue的四川美食分享网站。Javaee项目&#xff0c;springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的四川美食分享网站&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&am…

python网络相册设计与实现flask-django-nodejs-php

此系统设计主要采用的是python语言来进行开发&#xff0c;采用django框架技术&#xff0c;框架分为三层&#xff0c;分别是控制层Controller&#xff0c;业务处理层Service&#xff0c;持久层dao&#xff0c;能够采用多层次管理开发&#xff0c;对于各个模块设计制作有一定的安…

【Java基础】了解Java安全体系JCA,使用BouncyCastle的ED25519算法生成密钥对、数据签名

文章目录 一.Java安全体系结构二.JCA和JCE三.CSP(加密服务提供程序)与Engine类1.CSP2.Engine类如何使用引擎类 四.查看当前JDK支持的算法服务提供商(Provider)五.BouncyCastle是什么六.如何使用BouncyCastle&#xff1f;七.bouncycastle实现ED25519工具类 一.Java安全体系结构 …

python文学名著分享系统的设计与实现flask-django-nodejs-php

在此基础上&#xff0c;结合现有文学名著分享体系的特点&#xff0c;运用新技术&#xff0c;构建了以python为基础的文学名著分享信息化管理体系。首先&#xff0c;以需求为依据&#xff0c;根据需求分析结果进行了系统的设计&#xff0c;并将其划分为管理员和用户二种角色和多…

【剑指offer】24. 机器人的运动范围(java选手)

题目链接 题目链接 题目描述 地上有一个 m 行和 n列的方格&#xff0c;横纵坐标范围分别是 0∼m−1 和 0∼n−1。 一个机器人从坐标 (0,0) 的格子开始移动&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#xff0c;下四个方向移动一格。 但是不能进入行坐标和列…

NIVision-相机图像采集

应用场景 上位机与工业相机通讯&#xff0c;控制相机抓取图像。 工业相机的通讯接口大多为USB口或网口。 USB口则直接将通讯线缆插入上位机USB端口&#xff0c;打开MAX中设备与接口一栏可以看到电脑给相机分配的资源名称&#xff1b;网口则需要将网线连接相机和上位机&#xf…

uniapp的本地存储?

在uni-app中&#xff0c;你可以使用uni.setStorageSync和uni.getStorageSync来进行本地存储的操作。下面是一个简单的示例&#xff1a; // 将数据存储到本地 uni.setStorageSync(key, value);// 从本地获取数据 let data uni.getStorageSync(key); console.log(data); // 输出…

(附源码)基于Spring Boot + Vue 在线网课学习系统的设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31…

小程序最大页面跳转是几次?

小程序最大页面跳转次数是10次。在小程序的生命周期内&#xff0c;每次页面跳转都会被计入这个次数限制。

Llama 2 模型

非常清楚&#xff01;&#xff01;&#xff01;Llama 2详解 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/649756898?utm_campaignshareopn&utm_mediumsocial&utm_psn1754103877518098432&utm_sourcewechat_session一些补充理解&#xff1a; 序列化&#xff…

SQL运维_Unix下MySQL-8.0.18配置文件示例

SQL运维_Unix下MySQL-8.0.18配置文件示例 MySQL 是一个关系型数据库管理系统, 由瑞典 MySQL AB 公司开发, 属于 Oracle 旗下产品。 MySQL 是最流行的关系型数据库管理系统之一, 在 WEB 应用方面, MySQL 是最好的 RDBMS (Relational Database Management System, 关系数据库管…

使用阿里CICD流水线打包Java项目到阿里的docker镜像私仓,并自动部署到服务器启动服务

文章目录 使用阿里CICD流水线打包Java项目到阿里的docker镜像私仓&#xff0c;并自动部署到服务器启动服务1、功能原理实现2、将自己的Java项目通过Git上传到阿里的代码仓库中&#xff0c;也可以通过绑定Gitee或者GitHub账号进行导入3、创建自己的阿里云镜像私仓3、进入阿里的C…

GPT+向量数据库+Function calling=垂直领域小助手

引言 将 GPT、向量数据库和 Function calling 结合起来&#xff0c;可以构建一个垂直领域小助手。例如&#xff0c;我们可以使用 GPT 来处理自然语言任务&#xff0c;使用向量数据库来存储和管理领域相关的数据&#xff0c;使用 Function calling 来实现领域相关的推理和计算规…