本周小贴士#61:默认的成员初始化器

本文介绍了C++中的默认成员初始化器,它允许在声明时为类的成员设置默认值,减少了遗漏初始化的错误。默认初始化器适用于各种数据类型,包括bool、int、double和指针。当构造函数存在时,可以覆盖默认初始化。同时,文章强调了成员初始化器与静态成员初始化器的区别,并提醒程序员注意避免混淆。
摘要由CSDN通过智能技术生成

作为Totw#61最初始发表于2013年11月12日
由Michael Chastain(mec.desktop@gmail.com)创作
更新于2016年10月

声明默认成员初始化

默认的成员初始化器在构造函数之前为成员声明默认值,如下所示:

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

默认初始化器会传播到该类的所有的构造函数,甚至C++合成的构造函数。用这种方式初始化有许多数据成员的类是非常有用的,尤其是像bool、int、double和原生指针这类数据成员。这些基础类型的非静态数据成员经常从空隙中溜走,最终没有初始化。不过,任意类型的非静态数据成员都可能有初始化器。
默认成员初始化器对于那些用户没有编写构造函数的简单结构体的声明也是有用的:

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 };
};

成员初始化器的重写

如果一个类的构造函数初始化了一个已经有默认初始化器的数据成员,那么在构造函数中的初始化将替代默认构造函数:

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_有一个非静态的类成员初始化器
  const size_t length_ = strlen(ptr_);
};

这段代码等价于这旧的代码:

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_;
};

请注意,第一个和第二个Frobber构造函数对于它们的非静态变量有初始化器;这两个构造函数不会为length_使用默认的初始化器。第三个Frobber构造函数针对length_没有初始化器,所以构造函数将使用默认的初始化器来为length_初始化。
与平常在C++中一样,所有的非静态变量都会按照它们声明的顺序来初始化。
在这3个Frobber构造函数的前2个中,构造函数为length_提供初始化器。构造函数初始化器替代默认的成员初始化器——非静态类成员初始化器不会为构造函数增加代码的生成。
注意:早期的文档可能认为默认的成员初始化器是非静态数据成员初始化器,缩写为NSDMIs。

结论

默认的成员初始化器不会让你的程序变得更快。它们将帮助减少来自遗漏的错误,尤其是当某人添加新的构造函数或新的数据成员时的遗漏。
小心,不要混淆非静态类成员初始器和静态类成员初始化器:

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

这是一个较老的特性。counter_是静态的,这是一个带有初始化器的静态声明。这与非静态类成员初始化器是不同的,正如静态成员变量不同于非静态成员变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值