Tip of the Week #61: Default Member Initializers

2023-10-29

Tip of the Week #61: Default Member Initializers

Originally posted as Totw #61 on Nov 12, 2013
by Michael Chastain (mec.desktop@gmail.com)
Updated October, 2016

Declaring Default Member Initialization

一个默认的成员初始化声明是用于给成员在构造的时候提供一个默认值,看起来像下面这段代码:

class Client {
 private:
  int chunks_in_flight_ = 0;
};

这种默认的成员初始化会自动添加到类的所有构造函数中,甚至包括C++编译器合成的构造函数。类的成员默认初始化这种方式对于拥有众多数据成员的类来说很有用,尤其是对于像boolintdouble和裸指针等类型。这些基本类型的非静态的数据成员经常会忘记在构造函数中进行初始化,但是任何类型的非静态数据成员都可能具有初始化程序。

Non-static data members of any type may have initializers, though. 最后一句翻译的不好,感觉没有上下文

默认的成员初始化对于那些用户没有编写构造函数的简单结构来说,也很有用:

struct Options {
  bool use_loas = true;
  bool log_pii = false;
  int timeout_ms = 60 * 1000;
  std::array<int, 4> timeout_backoff_ms = { 10, 100, 1000, 10 * 1000 };
};

Member Initialization Overrides

如果对一个已经有默认初始化值的数据成员在构造函数中再次进行了初始化,那么构造函数中的默认值将会覆盖默认的成员初始化值。

class Frobber {
 public:
  Frobber() : ptr_(nullptr), length_(0) { }
  Frobber(const char* ptr, size_t length)
    : ptr_(ptr), length_(length) { }
  Frobber(const char* ptr) : ptr_(ptr) { }
 private:
  const char* ptr_;
  // length_ has a non-static class member initializer
  const size_t length_ = strlen(ptr_);
}

上面的代码等同于下面这种C++98风格的代码:

class Frobber {
 public:
  Frobber() : ptr_(nullptr), length_(0) { }
  Frobber(const char* ptr, size_t length)
    : ptr_(ptr), length_(length) { }
  Frobber(const char* ptr)
    : ptr_(ptr), length_(strlen(ptr_)) { }
 private:
  const char* ptr_;
  const size_t length_;
}

注意最上面的代码中,Forbber的第一个和第二个构造函数对于非静态的数据成员都有进行初始化,这两个构造函数将不会使用给length_设置的默认初始化值。然后Forbber的第三个构造函数是没有对length_进行构造初始化的,因此这个构造函数中length_使用的是默认成员初始化的值。

和C++一样,所有的非静态变量都按其声明的顺序进行初始化。

Forbber的三个构造函数中的前两个,构造函数都length_成员提供了初始值。那么构造函数的初始化会替代默认的成员初始化,也就是说非静态的类成员初始化将不会为这些构造函数生成初始化的代码。

注意,一些来的文档可能将默认成员初始化称为非静态数据成员初始化,简写为NSDMIs.

Conclusion

默认的成员初始化不会让你的程序变的更快,它只会帮助你减少因为遗漏导致的bug,尤其是当有人添加新的构造函数或新的数据成员时。

主要不要将非静态的类成员初始化与静态的类成员初始化混淆。

class Alpha {
 private:
  static int counter_ = 0;
};

这是一个老的特性,counter_是一个static类成员,这是带有初始化值的的静态声明。这与非静态数据成员初始化是不同的。就像静态成员变量与非静态成员变量不同一样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tip of the Week #61: Default Member Initializers 的相关文章

  • C++构造函数

    文章目录 1 构造函数的定义及特征2 默认构造函数2 1 合成的默认构造函数2 1 1 默认初始化2 1 2 合成的默认构造函数初始化类成员变量的规则2 1 3 有些场合不能使用合成的默认构造函数 2 2 全缺省的默认构造函数 xff08
  • C++之struct构造函数(2010-10-19 15:04:47)

    C 43 43 之struct构造函数 2010 10 19 15 04 47 转载 标签 xff1a cpp struct 构造函数 校园 分类 xff1a C C PlusPlus 在网络协议 通信控制 嵌入式系统的C C 43 43
  • 构造函数设置为private,会怎样。

    构造函数设置为private 会怎样 1 无法静态的创建对象了 即不能通过 A a这种方式创建对象了 只能通过在类的内部的静态成员函数中new一个对象 动态的创建对象 include
  • JAVA随笔——关于构造函数与this关键字和static关键字

    函数重载 函数重载根据参数不同来进行分别 参数顺序不同也是函数重载 并非同一个函数 例如 public class OverloadingOrder public static void main String args f 1 z f f
  • 指针与引用的区别,指针与引用的底层实现是否一样?

    指针与引用 在More Effective C 的条款一有详细讲述 条款一 指针与引用的区别 指针与引用看上去完全不同 指针用操作符 和 gt 引用使用操作符 但是它们似乎有相同的功能 指针与引用都是让你间接引用其他对象 你如何决定在什么时
  • 在C++中子类继承和调用父类的构造函数方法

    构造方法用来初始化类的对象 与父类的其它成员不同 它不能被子类继承 子类可以继承父类所有的成员变量和成员方法 但不继承父类的构造方法 因此 在创建子类对象时 为了初始化从父类继承来的数据成员 系统需要调用其父类的构造方法 如果没有显式的构造
  • Tip of the Week #61: Default Member Initializers

    Tip of the Week 61 Default Member Initializers Originally posted as Totw 61 on Nov 12 2013 by Michael Chastain mec deskt
  • 【深入理解C++】调用父类的构造函数

    文章目录 1 子类的构造函数默认会调用父类的无参构造函数 2 调用父类的构造函数 1 子类的构造函数默认会调用父类的无参构造函数 include
  • C++中将构造函数或析构函数定义为private

    今天面试被问到了这个单例模式常用到的技术手段 下面进行分析 很多情况下要求当前的程序中只有一个object 例如一个程序只有一个和数据库的连接 只有一个鼠标的object 通常我们都将构造函数的声明置于public区段 假如我们将其放入pr
  • Tip of the Week #10: Splitting Strings, not Hairs

    Tip of the Week 10 Splitting Strings not Hairs Originally published as totw 10 on 2012 08 16 By Greg Miller jgm google c
  • 不要在构造和析构函数中调用虚函数

    注 本文对应Effective C 条款9 基类是一个模拟股票交易的类 成员函数logTransaction 是记录每一笔交易 具体买 卖派生类实现自己的记录函数 基类的构造函数中调用了这个虚函数 先来思考下面这段代码 include
  • C++【对象模型】

    文章目录 索引 一 默认构造函数 1 何时默认构造函数会自动生成 2 编译器合成有用的构造函数四种情况 2 1 类中内含带有默认构造的类成员 2 2 带有默认构造的基类 2 3 带有虚函数的类 2 4 带有一个虚基类的类 索引 C 对象模型
  • C++ 类 :有参数构造函数与无参数构造函数使用注意事项

    构造函数的作用是在创建类的对象时进行类对象初始化的 在 C 中 每个类都有且必须有构造函数 如果用户没有自行编写构造函数 则 C 自动提供一个无参数的构造函数 称为默认构造函数 这个默认构造函数不做任何初始化工作 一旦用户编写了构造函数 则
  • 结构体中存在string类型成员

    include
  • Java 构造函数的详解

    我们人出生的时候 有些人一出生之后再起名字的 但是有些人一旦出生就已经起好名字的 那么我们在java里面怎么在对象一旦创建就赋值呢 1 构造方法的作用 构造方法作用 对对象进行初始化 如图 2 构造函数与普通函数的区别 1 一般函数是用于定
  • 工厂函数和构造函数的区别

    工厂函数和构造函数的区别 下面是给出的两个都是实现 定义使用值的范围 的函数 第一个工厂函数 工厂模式 用以创建并初始化类的实例 而且给出了一个表示 值的范围 的类定义了原型对象 第二个是使用构造函数代替工厂函数来实现相同功能的代码段 下面
  • Java基础十一(private、this关键字和构造函数)

    私有private关键字 成员变量是否一定需要全部向外界访问 如果需要向外界访问 则public 如不需要向外界访问 则private 但是一般而言 都会将成员变量私有化 给成员变量 private是彻底不想给外界类中不需要对外提供的内容都
  • Envoy源码分析之ThreadLocal

    ThreadLocal机制 Envoy中的ThreadLocal机制其实就是我们经常说的线程本地存储简称TLS Thread Local Storage 顾名思义通过TLS定义的变量会在每一个线程专有的存储区域存储一份 访问TLS的时候 其
  • Tip of the Week #65: Putting Things in their Place

    Tip of the Week 65 Putting Things in their Place Originally posted as totw 65 on 2013 12 12 By Hyrum Wright hyrum hyrumw
  • C++编译器为类自动生成的函数

    我们可以构建一个空类 class Empty 尽管没有定义任何函数 但我们可以通过以下方式使用这个类 Empty e1 Empty e2 e1 e2 e1 因为当编译器发现你用上述方式使用这个类而却在类声明中没有定义一般构造函数 非复制构造

随机推荐

  • Python 中的<>和!= 区别

    今天在编写Python MySQL 采集脚本过程中 需要使用到 不等于 表达方式 第一种写法 在Python2 6以前版本 不等于 if string atof func get item mysql status Qcache hits
  • C++/C++11中头文件algorithm的使用

  • Ubuntu20.04 操作系统切换中文 & 安装中文输入法

    网上有很多的帖子指导如何安装搜狗输入法 我也尝试过 需要安装一些指令 解决依赖很麻烦 很消耗精力 也找不到简便的办法 因此还是用系统自带的输入法吧 一 换源 这一步很重要 系统下载输入法时 能够从阿里云服务器下载大大提升速度 具体请参考拙作
  • 中国数字经济发展指数报告(2023年)

    报告 显示 数字经济具有高度发展驱动性 各地区数字经济发展指数与地区综合经济实力具有高度正相关性 数字经济对于促进地区经济发展的驱动能力强劲 关注公众号 互联互通社区 回复 SZJJ396 获取全部报告内容 从总指数结果来看 我国数字经济呈
  • DDR3相关概念

    1 BL8 突发长度 理解一下概念 突发传输 在通信领域中一般指在短时间内进行相对高带宽的数据传输 Burst 突发 是指在同一行中相邻的存储单元连续进行数据传输的方式 BL突发长度 连续传输的周期数就是突发长度 在突发传输的模式下 多个数
  • tcp长连接的双向加密

    一 历史和基础 做即时通讯项目 网游登录等业务时 我们通常需要一种能在线回推的机制 这时候客户端的tcp长连接就可能派上用场了 示意图 二 问题产生 曾经做过一个项目 之前老的加密方案为 1 客户端发一个rsa公钥G1给服务端 明文 自己留
  • PaddleOCR详解和识别图片中文字

    前言 paddleocr可以说是最近ocr的主 军 家对于paddleocr的认可度是相当的 特别是最近推出的轻量级模型 可以识别近80种语 并且效率是这三种ocr工具种最 的 相同的图 paddleocr只需要2秒左右 对于多场景的 语种
  • 计算机键盘字母记忆,键盘26个字母口诀是怎样的?

    01 七 Q 碗 W 鹅 E 肉 R 汤 T 已 Y 无 W 一 Y 我 W 婆 P 爱 A 死 S 豆 D 腐 F 羹 G 回 H 家 J 快 K 乐 L 自 Z 行 X 车 C 未 V 帮 B 你 N 买 M 众所周知 计算机键盘字母是
  • MongoDB3.0+ 添加用户命令

    关键命令 db createUser user coolead pwd coolead roles role dbOwner db mycoolead C Program Files MongoDB Server 3 2 bin gt mo
  • matlabe基于残差学习的图像去噪_《利用组稀疏残差约束进行图像去噪》

    题目 利用组稀疏残差约束进行图像去噪 来源 Zha Z Liu X Zhou Z et al Image denoising via group sparsity residual constraint C 2017 IEEE Intern
  • Java do-while循环学习小结

    do while循环先执行循环 再判断条件 do while循环会至少执行一次 具体内容扫描关注公众号
  • Django基础之Model操作

    一 数据库操作 1 创建model表 基本结构 1 coding Utf8 2 from django db import models 3 4 class userinfo models Model 5 如果没有models AutoFi
  • 程序员工作交接文档怎么写_程序员如何优雅的做好离职交接工作?

    1背景 某项目负责人离职 仅在离职前不到一周工作交接给我 该项目特点 1 所有参与人员尽数几乎全部离职 2 项目开始时间 2012年 数易版本 已经4年多的大项目 3 涉及模块众多 部署文档已经没有最新的 4 有Git版本管理 但资料不全且
  • 三极管驱动电路(扩充单片机的输出电流)

    常见的三极管驱动有两种结构 共射极输出 共集电极输出 I 共射极输出 PNP 要求输入的动态范围要大 而且输出的电压范围永远比输入小0 7V 射极输出电路就不能有效的利用 5V的电源 实际上 加到继电器上的电压 不足 4V 除非是使用4V的
  • 2.2 Git 基础 - 记录每次更新到仓库

    2 2 Git 基础 记录每次更新到仓库 版本说明 版本 作者 日期 备注 0 1 loon 2019 3 19 初稿 目录 文章目录 2 2 Git 基础 记录每次更新到仓库 版本说明 目录 记录每次更新到仓库 Figure 8 文件的状
  • Android自定义View --- 绘制圆环

    Android自定义View实现很简单 继承View 重写构造函数 onDraw onMeasure 等函数 如果自定义的View需要有自定义的属性 需要在values下建立attrs xml 在其中定义你的属性 在使用到自定义View的x
  • C/C++内存泄漏的原因以及怎么解决

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 背景 一 malloc后未释放 二 未匹配 背景 提示 这里可以添加本文要记录的大概内容 C C 编程语言中 内存的分配与回收都是由开发人员主动进行的 比如使用ma
  • EJBCA操作说明(一)ejbca web界面操作

    java代码操作ejbca链接 1 EJBCA介绍 EJBCA是一个全功能的CA系统软件 它基于J2EE技术 并提供了一个强大的 高性能 可升级并基于组件的CA EJBCA兼具灵活性和平台独立性 能够独立使用 也能和任何J2EE应用程序集成
  • 音视频不同步问题的原因和解决方案

    FAQ 在播放视频的时候 尤其是网络视频或者高清视频 会有视频画面和对应的声音信息不同步的问题 这样的问题原因在哪里 如何解决 Resolve 避免音视频不同步现象有两个关键 一是 在生成数据流时要打上正确的时间戳 如果数据块上打的时间戳本
  • Tip of the Week #61: Default Member Initializers

    Tip of the Week 61 Default Member Initializers Originally posted as Totw 61 on Nov 12 2013 by Michael Chastain mec deskt