c++的对象初始化

忍不住了,不得不吐槽一下,妈的,太复杂了,真难,搞得太复杂了,看不懂,看不懂,真的越来越复杂了,没有必要啊!

看得了头皮发麻,搞不明白,咱又不是干编译器的,投降了。 工程代码中,代码风格要保持简洁,可读性好,可维护性好,没事千万别整一些奇奇怪怪的初始化秀技术,别过度依赖语言特性与编译器特性,最简单就是最好的!

我摊牌了,看了两天没有彻底看明白,我放弃了。把我看明白的部分作一下笔记,免得后续忘记了又重复看,浪费时间。

C++的初始化方式

见链接:https://en.cppreference.com/w/cpp/language/initialization

  • Value initialization, e.g. std::string s{};
  • Direct initialization, e.g. std::string s("hello");
  • Copy initialization, e.g. std::string s = "hello";
  • List initialization, e.g. std::string s{'a', 'b', 'c'};
  • Aggregate initialization, e.g. char a[3] = {'a', 'b'};
  • Reference initialization, e.g. char& c = a[0];

只介绍一下值初始化与聚合初始化, 因为很常用,尤其是咱们初始化结构体对象时。

值初始化

使用空的{}进行值初始化。(即然c++11已经引入了{}, 咱们也就别使用()了吧,也就提了)。

规则是这样的:

  1. if T is a class type with no default constructor or with a user-provided or deleted default constructor, the object is default-initialized;
  2. if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;
    however, all known compilers come into case (2) when a non-deleted defaulted default constructor is selected by overload resolution, even if there is a user-provided default constructor, see Notes;
  3. if T is an array type, each element of the array is value-initialized;
  4. otherwise, the object is zero-initialized.

我只记两点:
第一:当对一个类对象提供了默认构造函数时,进行值初始化时,会执行你提供的构造函数,如果你的构造函数内未对成员变量进行初始化,它们就是未初始化状态。

第二:当用户不提供任何构造函数时,编译器会生成默认的构造函数,进行值初始化时,会首先进行零初始化,然后再调用默认生成的构造函数(non-trivial时)。

聚合初始化

针对聚合体,会进行聚会初始化, 使用 {arg1, arg2, ...}的格式。

什么是聚合体,满足这些条件就是了:(V__V, 头大,详细见 该链接处

  • no private or protected direct (since C++17)non-static data members
  • no user-declared constructors (until C++11)
  • no user-provided constructors (explicitly defaulted or deleted constructors are allowed)(since C++11)(until C++17)
  • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)(since C++17)(until C++20)
  • no user-declared or inherited constructors(since C++20)
  • no virtual, private, or protected (since C++17) base classes
  • no virtual member functions
  • no default member initializers (since C++11) (until C++14)

聚合初始化的规则,详细见此处。 我只提取了下面几条对我有用的(我只用于初始化trival的结构体):

  1. 如果列表的参数个数大于实际要初始化项的数目, 编译报错。
  2. 如果列表的参数个数小于实际要初始化项的数目, 剩余初始化为0.
  3. 如果为空{}, 全部初始化为0.

强烈建议

  1. c++11已经引入了类内成员初始化, 尽可能使用class 类对象内成员初始化,多方便简洁啊! 其次使用初始化列表。如果类内的数据结构复杂,那就老老实实的定义好各种构造函数。
  2. 对于struct结构体, 很多情况下,往往都没有初始值,要对struct对象的所有成员进行零初值操作,退荐使用空{}, 如果对部分成员初始化,使用{初始值1, 初始值2 ...}的形式。
  3. 简洁永远是最好的,保持好的编程习惯!
posted @ 2021-06-02 00:12  殷大侠  阅读(781)  评论(0编辑  收藏  举报