c++继承构造函数

【1】为什么需要继承构造函数?

首先,看看如下代码片段:

复制代码

 1 struct A2 { 3     A(int i)4     {} 5 }; 6 7 struct B : A8 { 9     B(int i) : A(i)
10     {}
11 };

复制代码

在C++中非常常见:B派生于A,B在构造函数中调用A的构造函数,从而完成构造函数的“传递”。

有时候,基类可能拥有数量众多的不同版本的构造函数(这样的情况并不少见)。

那么,倘若基类中有大量的构造函数,而派生类却只有一些成员函数时,那么对于派生类而言,其构造就等同于构造基类。

为了遵从语法规则,就需要写很多的“透传”的构造函数。如下面这个例子:

复制代码

struct A
{A(int i) {} A(double d, int i) {} A(float f, int i, const char* c) {} // ... 
}; struct B : A 
{ B(int i) : A(i) {}B(double d, int i) : A(d, i) {}B(float f, int i, const char* c) : A(f, i, c) {} // ... virtual void ExtraInterface() {} 
};

复制代码

在构造B的时候想要拥有A这样多的构造方法的话,就必须一—“透传”各个接口。这无疑是相当不方便的。

而引入继承构造函数的机制就是为了解决这种麻烦的。

【2】using声明

我们知道C++中已经有一个好用的规则:

如果派生类要使用基类的成员函数(被隐藏)的话,可以通过using声明(using-declaration)来完成。请看如下示例:

(1)不声明基类成员函数:

基类成员函数被隐藏(关于隐藏可以参考《重载、覆盖、隐藏》),在派生类中不做声明:

复制代码

 1 #include <iostream>2 using namespace std;3 4 struct Base5 { 6     void f(double i)7     { 8         cout << "Base:" << i << endl;9     }
10 };
11 
12 struct Derived : Base
13 { 
14 //  using Base::f; // 声明基类Base的f函数
15     void f(int i)
16     { 
17         cout << "Derived:" << i << endl; 
18     } 
19 };
20 
21 int main() 
22 { 
23     Base b;
24     b. f(4.5);
25     Derived d;
26     d. f(4.5);
27 }
28 
29 /*
30 Base:4.5
31 Derived:4
32 */

复制代码

编译警告:warning C4244 : “参数”: 从“double”转换到“int”,可能丢失数据

再结合运行结果分析,说明执行的是派生类Derived中参数为int类型的函数f。

(2)声明基类成员函数:

复制代码

 1 #include <iostream>2 using namespace std;3 4 struct Base5 { 6     void f(double i)7     { 8         cout << "Base:" << i << endl;9     }
10 };
11 
12 struct Derived : Base
13 { 
14     using Base::f; // 声明继承基类Base的f函数
15     void f(int i)
16     { 
17         cout << "Derived:" << i << endl; 
18     } 
19 };
20 
21 int main() 
22 { 
23     Base b;
24     b. f(4.5);
25     Derived d;
26     d. f(4.5);
27 }
28 
29 /*
30 Base:4.5
31 Base:4.5
32 */

复制代码

编译无警告,再结合运行结果分析:

说明执行的是基类Base中参数为double类型的函数f。

同时,可以看到派生类Derived中其实有两个f函数的版本。

经过以上的分析,在C++11中,这个特性被扩展到了构造函数上。

即派生类可以通过使用using声明来继承基类的构造函数。

【3】应用继承构造函数

如上示例1,应用继承构造函数,改造如下:

复制代码

 1 #include <iostream>2 using namespace std;3 4 struct A5 {6     A(int i = 10) : m_a(i)7     {}8 9     int m_a;
10 };
11 
12 struct B : A
13 {
14     using A::A;  // 继承构造函数
15 
16     int m_b{ 100 };
17 };
18 
19 int main()
20 {
21     B b;
22     cout << b.m_a << endl; // 10
23     cout << b.m_b << endl; // 100
24 
25     B bb(200);
26     cout << bb.m_a << endl; // 200
27     cout << bb.m_b << endl; // 100
28 }

复制代码

通过using A::A的声明,把基类中的构造函数全部继承到派生类B中。

应用注意项:

(1)C++11标准更精巧的是,继承构造函数被设计为跟派生类中的各种类默认函数(默认构造、析构、拷贝构造等)一样,是隐式声明的。

这意味着如果一个继承构造函数不被相关代码使用,编译器不会为其产生真正的函数代码。

这无疑比“透传”方案总是生成派生类的各种构造函数更加节省目标代码空间。

(2)继承构造函数只会初始化基类中成员变量,对于派生类中的成员变量,则无能为力。

不过配合C++11中类成员的初始化表达式,为派生类成员变量设定一个默认值还是没有问题的。

比如此例中的m_b成员变量,设定默认值为100。

(3)基类构造函数的参数可能会有默认值。

对于继承构造函数来讲,基类构造函数参数的默认值是不会被继承的。

比如此例中的bb对象,利用实参200进行构造对象,结果m_a的值为200,而不是默认的10。

(4)基类构造函数有默认值会导致基类产生多个构造函数的版本,这些版本都会被派生类继承。

比如此例中,事实上,构建对象b,使用的均是默认构造函数;构建对象bb,使用的均是带一个参数的构造函数版本。

(5)有的时候,还会遇到继承构造函数“冲突”的情况。这通常发生在派生类拥有多个基类的时候。

多个基类中的部分构造函数可能导致派生类中的继承构造函数的函数名、参数(有的时候,我们也称其为函数签名)都相同,

那么继承类中的冲突的继承构造函数将导致不合法的派生类代码,如下示例:

复制代码

1 struct A { A(int) {} };
2 
3 struct B { B(int) {} };
4 
5 struct C : A, B
6 {
7     using A::A;
8     using B::B;
9 };

复制代码

这种情况下,可以通过显式定义继承类的冲突的构造函数,阻止隐式生成相应的继承构造函数来解决冲突:

复制代码

1 struct A { A(int) {} };
2 
3 struct B { B(int) {} };
4 
5 struct C : A, B
6 {
7     C(int c) : A(c), B(c) 
8     {}
9 };

复制代码

(6)如果基类的构造函数被声明为私有成员函数,或者派生类是从基类中虚继承的,那么就不能够在派生类中声明继承构造函数。

(7)如果基类的构造函数没有默认构造函数,那么一旦使用了继承构造函数,编译器也不会再为派生类生成默认构造函数。

如下示例不能够通过编译:

复制代码

 1 struct A 2 { 3     A(int) {} 4 };5 6 struct B : A 7 { 8     using A::A; 9 };
10 
11 int main()
12 {
13     B objB; // C2280 “B::B(void)”: 尝试引用已删除的函数
14 }

复制代码

个人认为,解决这种问题有两种方式,代码如下:

复制代码

 1 #if 0 // 方式一:基类定义默认构造函数,派生类自然也就有了2 struct A { A(int a = 10) {} };3 struct B : A4 {5     using A::A;6 };7 #else // 方式二:派生类自定义默认构造函数8 struct A { A(int) {} };9 struct B : A
10 {
11     using A::A;
12     B(int c = 20) : A(c) 
13     {}
14 };
15 #endif
16 
17 int main()
18 {
19     B objB;
20 }

复制代码

如上所述。

good good study, day day up.

顺序 选择 循环 总结

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

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

相关文章

openAI注册/登录 报错汇总

目录 报错类型问题原因及解决**access denied**<br />**提示An error occurred**<br />**Not available**<br />**同一IP地址频繁注册**<br />**cloudflare死循环验证**<br /> 最后 报错类型 access denied You do not have access to chat.op…

【Java面试题】真实的二面面试题(参考答案为纯个人理解)

1. 你掌握前端的哪些知识&#xff1f; vue2element-ui了解一些css,js 2. 那你说一下vue中的路由吧&#xff1f; vue中的路由是用来设定访问路径的,将路径映射到组件页面上 3. 说一下前端vue页面之间传参的方式&#xff1f; 路由查询字符串(我用的) // 路由定义 { path: /a…

yolo

目标检测 导言&#xff1a;目标检测的任务表述 如何从图像中解析出可供计算机理解的信息&#xff0c;是机器视觉的中心问题。深度学习模型由于其强大的表示能力&#xff0c;加之数据量的积累和计算力的进步&#xff0c;成为机器视觉的热点研究方向。 那么&#xff0c;如何理解…

神经网络与深度学习-学习笔记(5)

1.目标检测与YOLO 目标检测问题 目标检测是在给定的图片中精确找到物体所在位置&#xff0c;并标注出物体的类别。物体的尺寸变化范围很大&#xff0c;摆放物体的角度&#xff0c;姿态不定&#xff0c;而且可以出现在图片的任何地方&#xff0c;并且物体还可以是多个类别。 目…

可见光遥感目标检测(一)任务概要介绍

前言 本篇开始对遥感图像的目标检测进行介绍&#xff0c;介绍了其目标前景、数据集以及评价指标。 本教程禁止转载。同时&#xff0c;本教程来自知识星球【CV技术指南】更多技术教程&#xff0c;可加入星球学习。 Transformer、目标检测、语义分割交流群 欢迎关注公众号CV技…

YOLOv5全面解析教程①:网络结构逐行代码解读

撰文 | Fengwen, BBuf 本教程涉及的代码在&#xff1a; https://github.com/Oneflow-Inc/one-yolov5 教程也同样适用于 Ultralytics/YOLOv5&#xff0c;因为 One-YOLOv5 仅仅是换了一个运行时后端而已&#xff0c;计算逻辑和代码相比 Ultralytics/YOLOv5 没有做任何改变&#x…

可见光遥感图像目标检测(三)文字场景检测之Arbitrary

前言 前面介绍了关于可见光遥感图像目标检测任务主要面临的问题&#xff0c;现在对旋转目标的问题进行优化&#xff0c;为了便于大家理解与之前通用目标检测区别&#xff0c;采用Faster-Rcnn网络模型的架构对旋转目标的检测进行改进。 本教程禁止转载。同时&#xff0c;本教程来…

yolov5的简单使用

yolov5是什么 来自chatGPT的描述如下 YOLOv5是一种目标检测算法&#xff0c;它是YOLO系列算法的最新版本&#xff0c;由Joseph Redmon和Alexey Bochkovskiy等人开发。与之前的版本相比&#xff0c;YOLOv5在准确性和速度方面都有所提高。YOLOv5使用一种名为“Bag of Freebies”…

yolov3_spp项目中的各种配置文件读取

目录 1. open 函数 2. cfg文件夹下文档解析 2.1 hyp.yaml 2.2 my_yolov_3.cfg 3. data文件夹下文档解析 3.1 my_data.data 3.2 其它 后缀名 .ymal .txt .json .cfg .data .names .shapes 可以自定义后缀名&#xff1f;&#xff1f; pyhon文件操作大…

目标检测算法——YOLOv5/YOLOv7改进之结合CBAM注意力机制

&#x1f496;&#x1f496;>>>加勒比海带&#xff0c;QQ2479200884<<<&#x1f496;&#x1f496; &#x1f340;&#x1f340;>>>【YOLO魔法搭配&论文投稿咨询】<<<&#x1f340;&#x1f340; ✨✨>>>学习交流 | 温澜潮…

​目标检测算法——YOLOv5/YOLOv7改进之结合Criss-Cross Attention

&#xff08;一&#xff09;前沿介绍 论文题目&#xff1a;CCNet: Criss-Cross Attention for Semantic Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/1811.11721.pdf 代码地址&#xff1a;https://github.com/shanglianlm0525/CvPytorch 本文是ICCV2019的语义分…

目标检测算法——YOLOv5/YOLOv7改进之GSConv+Slim Neck(优化成本)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 目录 &#xff08;一&#xff09;前言 1.GSConv模块 2.Slim Neck&#xff08;GSBottleneckVoVGSCSP&#xff09; &#xff08;二&#xff09;YOLOv5改进之GSConvSlim Neck 1.配置common.py文件 2.配置yo…

目标检测算法——YOLOv5改进|增加小目标检测层

&#x1f496;&#x1f496;>>>加勒比海带&#xff0c;QQ2479200884<<<&#x1f496;&#x1f496; &#x1f340;&#x1f340;>>>【YOLO魔法搭配&论文投稿咨询】<<<&#x1f340;&#x1f340; ✨✨>>>学习交流 | 温澜潮…

【学习笔记】YOLOv5训练自己的数据集

训练自己的数据集进行总结&#xff0c;方便接下来的学习 目录 1.设置文件夹 2.标记自己的数据集 2.1在百度图片上找到自己想要的图片并批量下载 2.2labelimg软件的使用 3.修改配置文件 3.1AOCAO parameter.yaml 3.2AOCAO model.yaml 4.开始训练 4.1改代码 4.2训练过…

Tips and tricks for Neural Networks 深度学习训练神经网络的技巧总结(不定期更新)

文章目录 本文说明Debug 技巧Overfit一个简单的Batch无法复现之前的结果 数据处理平衡数据数据增强&#xff08;Data Augmentation&#xff09;图片增强 使用Embedding数据压缩数据标准化&#xff08;Normalization&#xff09;标签平滑&#xff08;LabelSmoothing&#xff09;…

官方正品 | Ultralytics YOLOv8算法来啦(尖端SOTA模型)

&#x1f496;&#x1f496;>>>加勒比海带&#xff0c;QQ2479200884<<<&#x1f496;&#x1f496; &#x1f340;&#x1f340;>>>【YOLO魔法搭配&论文投稿咨询】<<<&#x1f340;&#x1f340; ✨✨>>>学习交流 | 温澜潮…

暑期学习杂记

7月6日 粗略复习51&#xff08;问了学长后&#xff0c;我打算直接看小车视频&#xff0c;遇到不会的再回去看江科大&#xff09; 51单片机 LED灯共阳 数码管共阴 7月7日 定时器时间计算 [参考(1条消息) 51单片机定时器使用与计算-----day3_单片机定时器定时时间计算_电子笔记…

Raki的读paper小记:Retentive Network: A Successor to Transformer for Large Language Models

Abstract&Introduction&Related Work 研究任务 语言模型的基础架构已有方法和相关工作 S4&#xff0c;H3&#xff0c;Hyena&#xff0c;Linear Transformer用核函数近似注意力&#xff0c;以便将自回归推理重写为循环形式回归到使用循环模型进行高效推理&#xff0c;但…

Coremail RSAC大会观察:在邮件安全领域AI既是矛也是盾

《Coremail RSAC大会观察&#xff1a;在邮件安全领域AI既是矛也是盾》 全球网络安全界的盛会——2023年RSAC大会于当地时间4月24日-27日在美国旧金山召开&#xff0c;大会以“Stronger Together&#xff08;一起变得更强大&#xff09;”为主题&#xff0c;议程主要包含安全研…

小红书软件,自动文案神器,爆文效率UP

小红书软件&#xff0c;自动文案神器&#xff0c;爆文效率UP&#xff01;#小红书推广#小红书营销#百收小红书 Hello大家好&#xff0c;我是百收&#xff0c;今天给大家分享的是小红书&#xff0c;三步快速打造爆款笔记可批量可复制。那话不多说先给大家看一下呃&#xff0c;学…