编程C++开发者

在C++中,非静态类成员的内联初始化是什么,它在现代标准(C++11及以上)中的特点是什么?

用 Hintsage AI 助手通过面试

答案。

问题的历史:

在早期版本的C++中,所有类成员必须在构造函数的初始化列表或构造函数体内初始化。随着C++11的出现,允许直接在定义位置初始化非静态类成员——这大大提高了可读性并减少了未初始化变量的错误概率。

问题:

缺乏默认初始化会导致开发人员遇到不明显的行为,尤其是在出现新的构造函数时。没有保证类成员总是被初始化。这个方法的美妙之处在于减少了样板代码。

解决方案:

内联初始化为类成员指定默认值,如果在构造函数的初始化列表中没有明确初始化。

代码示例:

class Widget { int value = 42; std::string name{"default"}; public: Widget() {} Widget(int v) : value(v) {} };

关键特性:

  • 仅可使用C++11及以上。
  • 如果类成员在构造函数的初始化列表中被指定,则默认值会被忽略。
  • 仅适用于非静态成员。

具有陷阱的问题。

如果在构造函数的初始化列表中指定成员,内联初始化的值是否会被使用?

不会,将使用构造函数初始化列表中的值。示例:

class Test { int a = 10; public: Test(int x) : a(x) {} }; Test t(42); // a == 42

可以对类的静态成员进行内联初始化吗?

不能,仅限于非静态成员。静态类成员在类外单独初始化。

可以使用表达式来内联初始化类成员吗?

对于简单成员——可以(例如,调用构造函数或文字)。对于复杂计算,请使用函数或在构造函数中初始化。

常见错误和反模式

  • 尝试利用内联初始化来初始化静态类成员。
  • 期待始终使用默认值,即使在构造函数的初始化列表中被重写。
  • 使用复杂表达式进行内联初始化。

实际案例

负面案例

团队添加了一个新构造函数,但忘记初始化字段。它保持未初始化的值。访问变量时会崩溃。

优点:

  • 快速原型开发。

缺点:

  • 由于未初始化成员导致的难以识别的错误。

正面案例

对类的所有字段应用了内联初始化。在新的构造函数中无需显式指定初始化,减少了样板代码和错误的数量。

优点:

  • 安全性,明确性。
  • 新构造函数的添加变得简单。

缺点:

  • 并不总是适合复杂字段或依赖参数的初始化。