C++ 怎么调用父类构造函数 C++初始化列表调用基类构造写法【继承】

发布时间 - 2026-02-02 00:00:00    点击率:
父类构造函数必须在初始化列表中调用,不能在子类构造函数体内调用;多层继承时每层只调用直接父类,虚基类由最派生类显式调用;参数须为常量或构造函数参数,不可依赖未初始化成员;父类构造失败则整个对象构造中止。

父类构造函数必须在初始化列表里调用

子类对象构造时,父类部分必须先完成初始化,而 C++ 规定:基类构造函数**不能**在子类构造函数体内部调用(比如写成 Base::Base(42) 是非法的),只能通过成员初始化列表显式调用。

常见错误是试图在构造函数体内“手动调用”父类构造,结果编译失败,报错类似:error: constructor call in member initializer list is the only way to invoke a base class constructor

  • 正确写法:在子类构造函数声明后、函数体前的冒号 : 后列出 Base(args)
  • 如果父类有无参构造函数,且你不显式调用,编译器会自动插入默认调用;但一旦父类没有无参构造,就必须显式写
  • 初始化列表中,基类调用必须出现在所有成员变量初始化之前(顺序由继承声明顺序决定,不是书写顺序)

多层继承时怎么指定调用哪一层的父类构造

每层子类只负责调用**直接父类**的构造函数,不跨层。编译器会自动链式展开:最派生类 → 直接基类 → 间接基类。

例如 Derived : public MiddleMiddle : public Base,那么 Derived 的初始化列表只需写 Middle(x),而 Middle 自己的初始化列表里写 Base(y) —— Derived 不能也不该直接写 Base(z)

  • 若想让 Derived 控制 Base 的参数,需通过 Middle 构造函数透传(比如加一个带 int base_valMiddle 构造重载)
  • 虚继承下的基类构造由**最派生类**直接负责调用,这点例外 —— 如果 Base 是虚基类,Derived 初始化列表中必须显式调用 Base(...),否则即使 Middle 调用了也无效

初始化列表里调用父类构造时参数来源受限

初始化列表中所有表达式必须是常量表达式、参数名、或对 this 成员的简单访问(不能调用成员函数,也不能依赖尚未构造完成的成员)。

典型陷阱:想用子类成员变量的值去初始化

父类,比如:

class Derived : public Base {
    int x = 10;
public:
    Derived() : Base(x) {} // ❌ 错误!x 此时尚未初始化
};
  • 允许:直接使用构造函数参数,如 Derived(int v) : Base(v) {}
  • 允许:使用字面量、全局常量、constexpr 函数结果
  • 不允许:调用非 constexpr 成员函数、访问未初始化的成员、使用 this->xxx(此时 this 已存在但对象未完成构造)

父类构造失败会导致整个对象构造中止

如果父类构造函数抛出异常,子类构造函数体不会执行,且子类的析构函数也不会被调用(因为对象没构造成功)。这是 RAII 安全的关键前提。

这意味着:别指望在子类构造函数体里“兜底处理”父类初始化失败;异常必须向上抛出或在调用点捕获。

  • 若父类构造可能失败(如打开文件、分配资源),子类应做好异常传播准备
  • 不要在初始化列表中做可能失败的复杂逻辑 —— 应该封装进父类构造,或改用工厂函数 + std::optional/std::expected(C++23)等更明确的错误传递方式
  • 注意:初始化列表中多个基类/成员的构造顺序是固定的(先基类后成员,同级按声明顺序),异常发生时已成功构造的部分会逆序析构
实际写的时候最容易漏的是虚基类的显式调用,或者误以为能在函数体里补救父类初始化失败 —— 这些地方一错就编译不过或行为未定义。


# ai  # c++  # 常量  # 封装  # 成员变量  # 成员函数  # 父类  # 子类  # 构造函数  # 析构函数  # Error  # int  # 继承  # class  # public  # 对象  # constructor  # this  # 列表中  # 体内  # 能在  # 链式  # 派生类  # 抛出  # 有无  # 自己的  # 装进 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  免费网站制作appp,免费制作app哪个平台好?  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  图册素材网站设计制作软件,图册的导出方式有几种?  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  Laravel如何为API编写文档_Laravel API文档生成与维护方法  魔毅自助建站系统:模板定制与SEO优化一键生成指南  如何在云服务器上快速搭建个人网站?  如何用已有域名快速搭建网站?  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  Android中AutoCompleteTextView自动提示  javascript中闭包概念与用法深入理解  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  再谈Python中的字符串与字符编码(推荐)  如何快速使用云服务器搭建个人网站?  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理  Laravel如何生成URL和重定向?(路由助手函数)  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  微信小程序 五星评分(包括半颗星评分)实例代码  打造顶配客厅影院,这份100寸电视推荐名单请查收  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  微信公众帐号开发教程之图文消息全攻略  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  如何在阿里云虚拟服务器快速搭建网站?  网站建设要注意的标准 促进网站用户好感度!  如何基于PHP生成高效IDC网络公司建站源码?  Python3.6正式版新特性预览  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  LinuxShell函数封装方法_脚本复用设计思路【教程】  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  Linux后台任务运行方法_nohup与&使用技巧【技巧】  微信小程序 scroll-view组件实现列表页实例代码  C语言设计一个闪闪的圣诞树  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  JavaScript如何操作视频_媒体API怎么控制播放  如何选择可靠的免备案建站服务器?  企业网站制作这些问题要关注  Angular 表单中正确绑定输入值以确保提交与验证正常工作  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  如何快速生成专业多端适配建站电话?  javascript中的try catch异常捕获机制用法分析