前几天群里聊到了初始化,所以这次选择该主题。

这个主题也是一个基本内容,乃大厦之基,联系太过广泛,所以也是可深可浅。

局部值、全局值、成员值、静态值、内联值、线程值……每一个单独拿出来可能还好理解,但一组合起来就比较复杂了。有些内容,如果不懂操作系统、编译原理和汇编,还难以真正理解其来龙去脉。尤其是静态值,一个 static 本身就有十几种不同的意思,再和 inline, constexpr, constinit……一组合,可谓是复杂到了极点。

这次先来统一下变量初始化的相关术语,更多内容后面再来说。

C++ 初始化包含 default initialization, value initialization, direct initialization, copy initialization, list initialization, aggregate initialization, reference initialization 这么几种。

声明一个变量,不做任何初始化(或是类中的成员没有初始化),就会采用 default initialization。

比如

type t;
new type;

这里 type 可以是 primitive types 和 class-types,primitive types 的默认初始化是保持未初始化,class-types 会调用 default ctor。

要让 primitive types 和 class-types 都初始化,就需要采用 value initialization。

例子:

type t{};
type t();
new type();
new type{};

对于 class-types 来说,它的效果和 default initialization 相同,但这种方式,primitive types 会进行 zero initialization。也就是说,假如是int t; int t{},前者未初始化,后者会初始化为 0。

初始化对象时,如果不使用显式的 =,则会采用 direct initialization。

例子:

type obj(arg1, ...);
type(arg1, ...);
new type(arg1, ...);
static_cast<type>(obj);
[arg](){} // arg captured by value

初始化对象时,如果使用显式 = 或是隐式拷贝,则会采用 copy initialization。

例子:

type obj = other;
foo(other);   // pass by value
return other; // return by value
throw obj;

使用 {} 初始化叫 list initialization,它又可分为 value list initialization, direct list initialization 和 copy list initialization。

例子:

type obj{}; // value list initialization
type{arg};  // direct list initialization
type obj = {arg}; // copy list initialization

list initialization 有一种特殊情况称为 aggregate initialization,用于初始化数组或是简单的struct/class(叫 aggregate,不能有 ctors,所有成员必须 public)。

例子:

type t = {arg1, ...}
type t{arg1, arg2};

C++20 下,aggregate initialization 又增加了一种新的初始化方式,叫 designated initializers,可以更方便地初始化。

point p { .x = .1, .y = .2 };

最后是 reference initialization,就是用来初始化引用的。

int& b= a;
type& ref { other };
type& ref = { arg1, arg2, ... }
point& ref = { .x = p.x, .y = p.y }

术语统一了,后面再来看其他的内容。

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use the Markdown in the comment form.