• 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. 简洁永远是最好的,保持好的编程习惯!
  • 相关阅读:
    git线上操作
    IDEA快捷方式
    Java 四种线程池
    java 获取当前天之后或之前7天日期
    如何理解AWS 网络,如何创建一个多层安全网络架构
    申请 Let's Encrypt 通配符 HTTPS 证书
    GCE 部署 ELK 7.1可视化分析 nginx
    使用 bash 脚本把 AWS EC2 数据备份到 S3
    使用 bash 脚本把 GCE 的数据备份到 GCS
    nginx 配置 https 并强制跳转(lnmp一键安装包)
  • 原文地址:https://www.cnblogs.com/yinheyi/p/14839418.html
Copyright © 2020-2023  润新知