c++中构造函数初始化列表怎么写_c++成员初始化语法【基础】
技术百科
穿越時空
发布时间:2026-01-24
浏览: 次 构造函数初始化列表在冒号后、函数体前用逗号分隔,直接调用成员构造函数初始化;必须用于const成员、引用成员及无默认构造函数的类类型成员,且初始化顺序按声明顺序而非列表顺序。
构造函数初始化列表的基本写法
构造函数初始化列表在 : 之后、函数体 {} 之前书写,用逗号分隔每个成员的初始化表达式。它不是赋值,而是直接调用成员的构造函数完成初始化。
常见错误是把初始化列表写成赋值语句,比如写成 MyClass() { a = 1; b = "hello"; } —— 这对内置类型看似可行,但对自定义类型(如 std::string、引用、const 成员)会编译失败或引发未定义行为。
class A { int x; std::string s; const int c; public: A() : x(0), s("default"), c(42) {} };- 顺序按类中成员声明顺序执行,与初始化列表中书写顺序无关
- 必须用初始化列表初始化:引用成员、
const成员、没有默认构造函数的类类型成员
哪些成员必须放在初始化列表里
以下三类成员无法在构造函数体内赋值,只能靠初始化列表:
-
const成员:一旦声明就不可修改,例如const int id; - 引用成员:引用必须绑定到有效对象,且不能重新绑定,例如
int& ref; - 没有默认构造函数的类类型成员:比如
std::vector默认可构造,但若你定义了v; class B { B(int); };,那么B b;就不合法,必须写成B b(5);在初始化列表中
漏掉这些会导致编译错误,典型提示如:member 'xxx' must be initialized by a mem-initializer in the constructor。
初始化列表 vs 构造函数体内赋值的区别
区别本质在于:初始化列表调用的是成员的构造函数;而函数体内赋值调用的是赋值运算符(operator=),前提是该成员已隐式构造完成。
- 对
std::string s;:初始化列表s("abc")直接调用string(const char*);函数体内s = "abc";先调默认构造函数,再调赋值,多一次开销 - 对自定义类,若其默认构造函数有副作用(如日志、资源申请),而你本意只想初始化为某个状态,那体内赋值等于“先做无用动作,再覆盖”,逻辑冗余甚至出错
- 内置类型(
int、double)两者性能无差别,但统一用初始化列表更一致、更安全
容易被忽略的细节和坑
初始化顺序只取决于成员在类中声明的顺序,而不是初始化列表里的顺序。这点极易被忽视,导致未定义行为。
- 例如:
class X { int a; int b; X() : b(0), a(b) {} };—— 尽管b写在前面,但a先声明,所以先初始化a,此时b还未构造,a会得到垃圾值 - 基类构造必须出现在派生类初始化列表最前面(隐式或显
式),否则编译报错
- 初始化列表中不能调用虚函数(因为此时虚表尚未完全设置好),即使语法允许,行为也是静态绑定
- 初始化列表中不能使用
this指针(对象尚未完全构造)
实际写代码时,建议把初始化列表写得和成员声明顺序严格一致,减少认知负担和潜在 bug。
# 的是
# 放在
# 绑定
# 自定义
# 就不
# 列表中
# public
# default
# 对象
# c++
# String
# int
# double
# class
# 区别
# 指针
# 构造函数
# this
# bug
# 体内
# operator
# 类中
# 隐式
# char
# 运算符
# 虚函数
# const
# constructor
# 直接调用
# 编译错误
# 赋值运算符
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何快速验证Golang安装是否成功_运行go v
- 如何理解Go指针和内存分配关系_Go Pointe
- Go语言中slice追加操作的底层共享机制解析
- Win11怎么清理C盘下载文件夹_Win11清理下
- Laravel 查询 JSON 列:高效筛选包含数
- Win11局域网共享怎么设置 Win11文件夹网络
- C++中的协变与逆变是什么?C++函数指针与返回类
- MAC如何隐藏文件夹及文件_MAC终端命令隐藏与第
- Windows10系统怎么查看显卡型号_Win10
- 当网站SEO排名下降时,如何应对?
- Win10如何设置双wan路由器 Win10双wa
- 如何使用Golang实现路由分组管理_Golang
- 如何在Golang中使用container/hea
- Win10如何卸载Skype_Win10卸载Sky
- C#怎么创建控制台应用 C# Console Ap
- Windows服务无法启动错误1067是什么_进程
- 如何在 Go 中正确反序列化多个同级 XML 元素
- Mac如何整理桌面文件_Mac使用堆栈功能一键整理
- Python类装饰器使用_元编程解析【教程】
- 如何在 Go 中判断变量是否为函数类型
- Win11怎么关闭透明效果_Windows11辅助
- Golang如何遍历目录文件_Golang fil
- 如何使用Golang管理跨项目依赖_Golang多
- 如何在Golang中实现微服务负载均衡_Golan
- Python 模块的 __name__ 属性如何由
- Win10怎么卸载剪映_Win10彻底卸载剪映方法
- 使用类变量定义字符串常量时的类型安全最佳实践
- Win11怎么设置屏保时间_调整Win11屏幕保护
- Windows怎样拦截WPS弹窗广告_Window
- Windows 10怎么隐藏特定更新补丁_Wind
- 如何使用Golang log设置日志输出格式_Go
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Windows怎样拦截QQ浏览器广告_Window
- MySQL 中使用 IF 和 CASE 实现查询字
- c++中如何使用std::variant_c++1
- c++如何实现多态性_c++ 虚函数表原理与动态绑
- 如何在Golang中捕获HTTP服务器错误_Gol
- Python lxml的etree和Element
- php命令行怎么运行_通过CLI模式执行PHP脚本
- Mac的“预览”如何合并多个PDF_Mac文件处理
- Python爬虫项目实战教程_Scrapy抓取与存
- Python网络超时处理_健壮性设计说明【指导】
- c++如何获取map中所有的键_C++遍历键值对提
- Win11系统更新后黑屏怎么办 Win11更新黑屏
- Win11应用商店下载慢怎么办 Win11更改DN
- Windows10如何删除Windows.old_
- mac怎么安装字体_MAC添加第三方字体与字体册管
- 如何使用Golang encoding/json解
- php485函数执行慢怎么优化_php485性能提
- Win11怎么开启专注模式_Windows11时钟


QQ客服