当前位置: 首页 > news >正文

C++ 标准特性:委托构造与继承构造

C++ 标准特性:委托构造与继承构造


一、委托构造函数(Delegating Constructor)—— C++11

1.1 概述

委托构造函数允许当前类的某个构造函数调用同类的其他构造函数来完成初始化。这样可以避免在多个构造函数中编写重复的初始化代码。

1.2 委托构造函数与普通构造函数的区别

区别点普通构造函数委托构造函数
成员初始值列表初始化成员变量只有一个参数,即同类中另一个构造函数
函数体
执行顺序初始化列表 → 函数体被委托函数初始化列表 →被委托函数函数体→ 委托构造函数函数体

关键规则:当被委托构造函数的函数体中有代码时,先执行完被委托构造函数的函数体,然后才会执行委托构造函数的函数体。

1.3 执行流程图解

委托构造函数 Test(int d) │ ├→ 调用被委托构造函数 Test("default", d) │ ├→ 初始化列表:_data(d), _str("default") │ └→ 函数体:cout << "普通构造函数" │ └→ 委托构造函数自身的函数体:cout << "委托构造函数"

1.4 示例代码

#include<iostream>usingnamespacestd;// 创建一个类classTestC{public:// 普通构造函数TestC(string s,intd):_data(d),_str(s){cout<<"程序执行:普通构造函数的函数体"<<endl;cout<<endl;}// 委托构造函数 ①:只传 int,string 用默认值TestC(intd):TestC("default",d){cout<<"程序执行:委托构造函数的函数体"<<endl;cout<<endl;}// 委托构造函数 ②:只传 string,int 用默认值TestC(string s):TestC(s,0){cout<<"程序执行:委托构造函数的函数体"<<endl;cout<<endl;}voidprintData(){cout<<"------程序执行:普通成员函数的函数体------"<<endl;cout<<"数据成员_data的值为:"<<_data<<endl;cout<<"数据成员_str的值为:"<<_str<<endl;cout<<endl;}private:int_data;string _str;};intmain(){TestCobjc1("hello",10);// 普通构造函数objc1.printData();TestCobjc2("helo",20);// 普通构造函数objc2.printData();TestCobjc3("hello");// 委托构造函数 → 内部调用 TestC("hello", 0)objc3.printData();return0;}

1.5 调用分析

对象构造方式实际调用链
objc1("hello", 10)普通构造直接匹配TestC(string, int)
objc2("helo", 20)普通构造直接匹配TestC(string, int)
objc3("hello")委托构造TestC(string)TestC("hello", 0)

二、继承构造函数(Inheriting Constructor)—— C++11

2.1 概述

在 C++ 中,构造函数不能是虚函数,因此构造函数不能被继承。但从 C++11 开始,可以通过using关键字达到继承构造函数的效果——让派生类"借用"基类的构造函数。

2.2 原理

  • using Base::Base;—— 派生类自动获得基类的所有构造函数
  • using Base::func;—— 派生类也可以引入基类的非虚成员函数

2.3 示例代码

#include<iostream>usingnamespacestd;structA{voidfunc(doubled){cout<<"基类A:"<<d<<endl<<endl;}};structB:A{// C++11 标准中,利用 using 关键字,使派生类可以继承父类的成员函数usingA::func;voidfunc(inti){cout<<"派生类:"<<i<<endl;}};intmain(){A a;a.func(78);// 调用 A::func(double)B b;b.func(87);// 调用 B::func(int),就近匹配return0;}

2.4 调用分析

调用匹配函数原因
a.func(78)A::func(double)A只有一个func78隐式转为double
b.func(87)B::func(int)B有两份func87精确匹配int版本
b.func(87.0)A::func(double)精确匹配double版本(由using引入)

using A::func;将基类的func(double)引入派生类的作用域,与派生类自己的func(int)构成重载关系。

2.5 using 继承构造函数(补充)

structBase{Base(intx){cout<<"Base(int)\n";}Base(intx,inty){cout<<"Base(int,int)\n";}};structDerived:Base{usingBase::Base;// 继承所有基类构造函数(C++11)};intmain(){Derivedd1(1);// 调用 Base(int)Derivedd2(1,2);// 调用 Base(int,int)return0;}

三、对比总结

特性委托构造继承构造(using)
关键词在初始化列表调用同类构造函数using Base::Base;
作用域同一类内部派生类与基类之间
解决什么问题避免多构造函数重复初始化让派生类可直接使用基类构造函数
执行顺序先被委托函数体 → 再委托函数体基类构造 → 派生类构造
C++ 版本C++11C++11

http://www.jsqmd.com/news/1081855/

相关文章:

  • 在当下,「.com」域名依然是首选,还是新顶级域名更具优势?
  • 绕过“失窃设备保护”:安装提取代理的替代方法
  • 嵌入式来电显示开发实战:Motorola Type 1/2电话解析库集成与调试
  • 2026怎么提取视频的文字?全平台视频转文字软件实测对比
  • 2026年B端抖音运营公司选型指南:聚焦实体与垂直行业的深度评测
  • 如何通过Chrome扩展轻松下载Jable.tv视频?
  • 如何免费使用DeepL翻译插件:3分钟打造你的浏览器翻译神器
  • Unity Mod Manager终极指南:5分钟掌握游戏模组管理艺术
  • 射频放大器评估板实战解析:从ISL74324M设计到产品集成指南
  • 嵌入式开发实战:从SCF5250手册到I2C、UART、QSPI与ColdFire核心应用
  • RAG评估实战:用RAGAs量化检索质量与生成忠实度
  • 嵌入式DSP性能分析实战:基于硬件计数器与CodeWarrior工具链的优化指南
  • 5分钟快速搭建个人专属Web邮箱系统:Roundcube Mail完整指南
  • 土建井道施工中的8个常见错误——做错一个,整改费上万
  • vSphere替代不是替换,是重构:从IaaS到云原生基础设施的7步迁移路线图(附Gartner验证框架)
  • VoiceFixer终极指南:3分钟学会AI音频修复,让受损语音重获清晰
  • 渗透测试之大模型靶场通关-llm-sec-range
  • 抖音内容下载终极指南:用开源工具5分钟搞定批量下载难题
  • 嵌入式DSP调试利器:TracePoint API实战与自动化性能分析
  • 终极指南:3种高效方法彻底解决Navicat Mac版试用期限制
  • py之mqtt-tls代码示例
  • 终极指南:如何用dnSpyEx进行专业级代码审查与智能分析
  • 联想 Moto 隐私空间开启教程,一台手机双空间,保护私人内容超实用
  • 嵌入式驱动开发实战:硬件抽象、内存管理与异构加速器集成
  • SCF5250硬件设计:JTAG调试模式配置与电气规格实战解析
  • Redis 缓存穿透、击穿、雪崩,我花了 3 年才分清它们的区别
  • FMA音乐分析数据集架构设计:企业级音乐信息检索解决方案
  • 3分钟快速搭建个人专属Web邮件系统:Roundcube Mail终极指南
  • ASP.NET Web Service SQL注入漏洞实战:从环境搭建到自动化利用与修复
  • 【JAVA毕设源码分享】基于SpringBoot的在线骑行网站的设计与实现(程序+文档+代码讲解+一条龙定制)