c++变量必须声明即初始化,禁止悬空赋值;局部变量不自动清零,全局/静态变量零初始化但不应依赖;类成员须用初始化列表;auto必须初始化;花括号初始化禁止窄化转换;成员初始化顺序由声明顺序决定而非初始化列表顺序。

变量声明和初始化必须在作用域内完成
C++ 不允许先声明后“悬空”赋值,尤其在函数外或类成员中,int x; 声明后若未初始化就使用,值是未定义的。局部变量不自动清零,哪怕写成 int x; 也绝不能假设它是 0。
- 函数内推荐直接初始化:
int count = 0;或std::string name{"Alice"}; - 全局/静态变量会零初始化(
int变成 0,指针变成nullptr),但别依赖这点来掩盖设计缺陷 - 类成员初始化必须在构造函数初始化列表里做,而不是构造函数体中赋值:
MyClass() : value_{42} {},否则默认构造+再赋值,浪费且可能出错
用 auto 推导时初始化不可省略
auto 不是“延迟类型决定”,而是靠初始化表达式推导类型,没初始化就无法推——auto x; 是非法的,编译直接报错 error: declaration of 'x' with no type。
- 正确写法只有:
auto x = 42;(推为int)、auto s = std::string{"hi"}; - 想推导引用?得显式写:
auto& ref = x;,auto ref = x;是拷贝 - 和
const搭配要注意:const auto y = 3.14;推出const double;但auto const z = 3.14;一样,顺序不影响语义
初始化语法有三种,行为差异很大
括号、等号、花括号初始化不是随便换着用的——尤其对 std::vector、自定义类型或窄化转换,结果可能完全不同。
-
int a(5);和int b = 5;对内置类型等价,但前者叫直接初始化,后者叫拷贝初始化(概念上) -
std::vector<int> v1(3, 1);</int>→ 含 3 个 1 的 vector;std::vector<int> v2 = {3, 1};</int>→ 含两个元素:3 和 1 -
double d{3.14159};安全;int i{3.14};编译失败(花括号禁止窄化转换),而int j = 3.14;会静默截断
类成员变量的初始化顺序由声明顺序决定,不是初始化列表顺序
即使你在构造函数初始化列表里把 y 写在 x 前面,只要类里 int x; 在 int y; 上面,x 就一定先被初始化——这个顺序编译器强制执行,改不了。
立即学习“C++免费学习笔记(深入)”;
- 如果
y初始化依赖x的值,但x还没初始化完,就会读到垃圾值 - 常见错误:
class C { int x_; int y_; C() : y_(x_ + 1), x_(42) {} };→y_用的是未初始化的x_ - Clang/GCC 加
-Wreorder能警告这种写法,建议打开










