• 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. 简洁永远是最好的,保持好的编程习惯!
  • 相关阅读:
    4、现有的命名方式有多少种?请举例说明。
    第二次作业
    第一次作业
    RateLimiter源码
    使用ASM字节码框架实现动态代理
    Java流机制学习
    Java8 Stream 学习总结
    XML实体解析器的作用
    DefaultResouceLoader的设计
    RSA 非对称加密 数字签名 数字证书
  • 原文地址:https://www.cnblogs.com/yinheyi/p/14839418.html
Copyright © 2020-2023  润新知