类成员初始化的首选方式?

2024-04-08

class A { public: int x[100]; };

声明A a不会初始化对象(通过字段中的垃圾值可以看出x)。 以下将触发初始化:A a{} or auto a = A() or auto a = A{}.

应该优先选择三者中的哪一个吗?

接下来,让我们让它成为另一个类的成员:

class B { public: A a; };

默认构造函数B似乎负责初始化a。 但是,如果使用自定义构造函数,我必须处理它。 以下两个选项有效:

class B { public: A a;  B() : a() { } };

or:

class B { public: A a{};  B() { } };

应该优先选择两者中的任何一个吗?


初始化

class A { public: int x[100]; };

声明A a不会初始化该对象(被垃圾看到 x) 字段中的值。

Correct A a定义时没有初始化程序,并且不满足以下任何要求默认初始化 http://en.cppreference.com/w/cpp/language/default_initialization.


1)以下将触发初始化:

A a{};

Yes;

  • a{}施行列表初始化 http://en.cppreference.com/w/cpp/language/list_initialization which
  • becomes 值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if {}是空的,或者可以是聚合初始化 http://en.cppreference.com/w/cpp/language/aggregate_initialization if A是一个聚合体。
  • 即使默认构造函数被删除也能正常工作。例如A() = delete;(如果“A”仍被视为聚合)
  • 将警告缩小转换范围。

2)以下将触发初始化:

auto a = A();

Yes;

  • This is copy initialization http://en.cppreference.com/w/cpp/language/copy_initialization where a prvalue temporary is constructed with direct initialization http://en.cppreference.com/w/cpp/language/direct_initialization () which
    • uses 值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if the ()是空的。
    • 没有希望聚合初始化 http://en.cppreference.com/w/cpp/language/aggregate_initialization.
  • 然后使用临时纯右值直接初始化 http://en.cppreference.com/w/cpp/language/direct_initialization物体。
  • Copy elision http://en.cppreference.com/w/cpp/language/copy_elision may be, and normally is employed, to optimize out the copy and construct A in place.
    • 允许跳过复制/移动构造函数的副作用。
  • 移动构造函数不能被删除。例如A(A&&) = delete;
  • 如果删除复制构造函数,则必须存在移动构造函数。例如A(const A&) = delete; A(A&&) = default;
  • 不会警告缩小转换。

3)以下将触发初始化:

auto a = A{}

Yes;

  • This is copy initialization http://en.cppreference.com/w/cpp/language/copy_initialization where a prvalue temporary is constructed with list initialization http://en.cppreference.com/w/cpp/language/list_initialization {} which
    • uses 值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if {}为空,或者可以是聚合初始化,如果A是一个聚合体。
    • 然后使用临时纯右值直接初始化 http://en.cppreference.com/w/cpp/language/direct_initialization物体。
  • Copy elision http://en.cppreference.com/w/cpp/language/copy_elision may be, and normally is employed, to optimize out the copy and construct A in place.
    • 允许跳过复制/移动构造函数的副作用。
  • 移动构造函数不能被删除。例如A(A&&) = delete;
  • 如果删除复制构造函数,则必须存在移动构造函数。例如A(const A&) = delete; A(A&&) = default;
  • 将警告缩小转换范围。
  • 即使默认构造函数被删除也能正常工作。例如A() = delete;(如果“A”仍被视为聚合)

应该优先选择三者中的哪一个吗?

显然你应该更喜欢A a{}.


成员初始化

接下来,让我们让它成为另一个类的成员:

class B { public: A a; };

默认构造函数B似乎负责初始化 的a.

不,这是不正确的。

  • the 隐式定义的'B' 的默认构造函数将调用A,但不会初始化成员。不会触发直接或列表初始化。陈述B b;对于此示例将调用默认构造函数,但留下不确定的值A的数组。

1)但是,如果使用自定义构造函数,我必须处理它。这 以下两个选项有效:

class B { public: A a;  B() : a() { } };

这会起作用;

  • : a() is a 构造函数初始值设定项 http://en.cppreference.com/w/cpp/language/function#Function_definition and a()是成员初始值设定项作为一部分成员初始值设定项列表 http://en.cppreference.com/w/cpp/language/initializer_list.
  • Uses 直接初始化 http://en.cppreference.com/w/cpp/language/direct_initialization () or, if ()是空的,值初始化 http://en.cppreference.com/w/cpp/language/value_initialization.
  • 不希望使用聚合初始化。
  • 不会警告缩小转换。

2) or:

class B { public: A a{};  B() { } };

这会起作用;

  • a现在有一个非静态数据成员初始值设定项 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html,如果您使用聚合初始化并且编译器是,则可能需要构造函数来初始化它不完全符合 C++14 https://blogs.msdn.microsoft.com/vcblog/2014/11/17/c111417-features-in-vs-2015-preview/.
  • 成员初始值设定项使用列表初始化 http://en.cppreference.com/w/cpp/language/list_initialization {} which
  • 可能会变成值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if {}为空或聚合初始化 http://en.cppreference.com/w/cpp/language/aggregate_initialization if A是一个聚合体。
  • If a是唯一的成员,则不必定义默认构造函数,并且默认构造函数将被隐式定义。

显然你应该更喜欢第二种选择。


就我个人而言,我更喜欢在任何地方使用大括号,一些例外 https://stackoverflow.com/a/18222927/1460794 for auto以及构造函数可能将其误认为的情况std::initializer_list:

class B { public: A a{}; };

A std::vector构造函数的行为会有所不同std::vector<int> v1(5,10) and std::vector<int> v1{5,10}. with (5,10)你得到 5 个元素,每个元素的值为 10,但是{5,10}你会得到两个分别包含 5 和 10 的元素,因为std::initializer_list如果您使用大括号,则强烈推荐。 Scott Meyers 的《Effective Modern C++》第 7 条对此进行了很好的解释。

专门针对成员初始值设定项列表 http://en.cppreference.com/w/cpp/language/initializer_list,可以考虑两种格式:

  • 直接初始化 http://en.cppreference.com/w/cpp/language/direct_initialization a()这变成值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if the ()是空的。
  • 列表初始化 http://en.cppreference.com/w/cpp/language/list_initialization a{}这也成为值初始化 http://en.cppreference.com/w/cpp/language/value_initialization if {}是空的。

幸运的是,在成员初始值设定项列表中,不存在最令人烦恼的解析的风险。在初始化列表之外,作为一个单独的语句,A a()会声明一个函数 vs.A a{}这本来就很清楚了。还,列表初始化 http://en.cppreference.com/w/cpp/language/list_initialization具有防止缩小转换的好处。

因此,总而言之,这个问题的答案是,这取决于您想要确定的内容,并且这将决定您选择的形式。对于空的初始化器,规则更加宽松。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类成员初始化的首选方式? 的相关文章

随机推荐

  • 在react-router 2中以编程方式重定向到页面

    我在用反应路由器 2 我想在成功登录或执行某些操作后以编程方式重定向到页面 我的路线文件是这样的 路线 js
  • Python 3.5 - Selenium - 如何处理新窗口并等待它完全加载?

    我正在做浏览器自动化 并且在某个时刻被阻止 此刻 我要求浏览器单击一个按钮 该按钮又打开一个新窗口 但有时互联网太慢 因此这个新窗口需要一些时间来加载 我想知道如何让 Selenium 等待这个新窗口完全加载 这是我的代码 driver s
  • 为什么 Java 客户端在运行时需要 WSDL?

    为 Java WS 客户端生成工件后 为什么需要 wsdllocation 参考 为什么运行时需要 WSDL 我可能会看到一些验证的原因 但这不应该是可选的吗 简介 虽然从设计角度来看 WSDL 对于 Web 服务客户端来说并不是必需的 但
  • Django:定义反向ForeignKey的名称

    我有两个模型 class Foo models Model foo field class Bar models Model foo models ForeignKey Foo on delete models CASCADE bar fi
  • 如何在没有实现任何模式的情况下操纵控件?

    我正在尝试通过实施自动化测试UIAutomation对于我们的项目 但许多控件不是标准的 并且也没有为这些控件实现适当的模式 我应该如何通过操作控件UI自动化框架在这种情况下 例如 我们产品中的按钮是通过 Pane 实现的 并且调用的模式也
  • .NET CLR 线程池耗尽 - 实现错误?

    我编写了一个简单的基于异步的负载测试库 它还有一个控制台界面可以从命令行进行测试 基本上 它同时运行大量请求 聚合它们 并显示摘要和简单的直方图 没有什么花哨 但我在本地系统中运行了大量测试 因此我想确保测试工具能够使用尽可能少的资源来获得
  • 如何从 64 位 .NET 应用程序打开 WOW64 注册表项

    我的 NET 应用程序 任何 CPU 需要读取 32 位程序创建的注册表值 在 64 位 Windows 上 它位于注册表中的 Wow6432Node 项下 我读到您不应该对 Wow6432Node 进行硬编码 那么使用 NET 访问它的正
  • 如何根据条件创建一个可以是多个字符串之一的常量?

    我想要不断地使用let这可能是几个值之一 例如 if condition1 constant hi else if condition2 constant hello else if condition3 constant hey else
  • 如何在Python中从邻接列表中选择子矩阵?

    我有一个邻接列表 其中每个数组代表该行的非零列 例如 下面的 adj 列表中的第 0 个数组意味着第 2 列和第 6 列为 1 其他所有列均为 0 adj list 2 6 1 3 24 2 4 3 5 21 4 6 10 1 5 7 6
  • 如何检测离子含量是否有滚动条?

    我想在离子内容上有或没有滚动条时隐藏或显示元素 更具体地说 我想在没有滚动条时显示一个按钮 在列表中加载更多项目 并在有滚动条的地方隐藏它 因此更多项目的加载是由 ion infinite scroll 完成的 我的 Ionic 应用程序也
  • 1 个节点存在 pod 在 kubernetes 集群中无法容忍的污点

    今天我的 kubernetes 集群 v1 15 2 给我这个错误 1 node s had taints that the pod didn t tolerate并且 Pod 无法启动 它告诉我一个节点有污点 我检查节点状态并且工作正常
  • 使用浏览器缓存进行增量更新

    客户端 AngularJS 应用程序 从服务器获取相当大的列表 列表可能有数百或数千个元素 这可能意味着未压缩的几兆字节 并且一些用户 管理员 获得更多数据 我不打算让客户端获得部分结果 因为排序和过滤不应该打扰服务器 压缩效果很好 大约为
  • 无法在 openpyxl 中保存 Excel 电子表格 - Python

    当我在 openpyxl 中时 我无法保存正在处理的活动文件 wb obj load workbook filename C Users timde PycharmProjects starshipit test xlsx read onl
  • nginx 和 apache2 上的 WordPress 重定向太多

    我刚刚在 ubuntu 14 04 LTS 上安装了 wordpress Nginx 充当 apache2 的反向代理 wp admin 工作正常 但我无法打开主页 Nginx 服务器代码 server listen 80 root var
  • INNER JOIN ON 与 WHERE 子句

    为简单起见 假设所有相关字段都是NOT NULL 你可以做 SELECT table1 this table2 that table2 somethingelse FROM table1 table2 WHERE table1 foreig
  • 如何重用所有场景的标题部分?

    我想重复使用header全部部分view controller scene header 部分表示绿色视图和标签 AMAR LIFE Here is my may 1st view controller scene 这是我的第一个视图控制器
  • R闪亮的分层下拉列表

    我们需要在 R闪亮中创建一个分层下拉列表 该列表至少有 3 个级别 您能帮我确定正确的库吗 请参考下面的图片供您参考 目前我们正在使用下面的代码 但是我们在下拉列表中得到了不正确的列 ui R library shiny library s
  • 是否可以在设备函数中调用cufft库调用?

    我在主机代码中使用 cuFFT 库调用 它们工作正常 但我想从内核调用 cuFFT 库 早期版本的 CUDA 没有这种支持 但是有了动态并行性 这可能吗 如果有任何关于如何实现这一目标的示例 那就太好了 尽管在 Kepler cc 3 5
  • 模拟forwardRef组件玩笑mockImplementation与打字稿

    当组件包装在forwardRef 中时 您打算如何处理测试文件中的模拟组件 mockImplementation 不在方法上 而是在属性渲染上 import React from react import Component from Co
  • 类成员初始化的首选方式?

    class A public int x 100 声明A a不会初始化对象 通过字段中的垃圾值可以看出x 以下将触发初始化 A a or auto a A or auto a A 应该优先选择三者中的哪一个吗 接下来 让我们让它成为另一个类