【问题标题】:In C++, what is the difference between X x = X(); type declaration and X x; declaration where X is the class [duplicate]在 C++ 中,X x = X(); 有什么区别?类型声明和 X x; X是类的声明[重复]
【发布时间】:2016-10-03 13:15:57
【问题描述】:

在我的代码中,我遇到了上述情况。在什么情况下我们需要使用上述的对象创建方式?我们不能简单地创建对象 X x 吗?我们在 X x = X() 中取得了什么成就;类型声明?

【问题讨论】:

  • 今天的答案是“没有”。但是,如果您不删除副本,那么理论上 X x = X() 默认允许首先构造两个 X 实例,然后将一个复制/移动分配给另一个。
  • @AndyG 即使有省略,仍然存在(轻微)差异:如果X 不可复制/可移动,则X x = X() 格式错误。
  • @AndyG 这取决于X。差异可能很大。这是默认初始化与值初始化。见stackoverflow.com/questions/1613341/…
  • 很公平,感谢您的澄清。
  • 另一个可能的重复:stackoverflow.com/q/1051379/27678

标签: c++


【解决方案1】:

有区别。 X x = X() 要求复制构造函数可以访问。

对于以下课程:

struct Foo
{
    Foo() = default;
    Foo(Foo const&) = delete;
    void* ptr;
};

这将编译:

Foo foo;

这不会:

Foo foo = Foo();

此外,第一种语法会导致默认初始化,因此 ptr 具有未确定的值,而第二种语法会将其零初始化为 nullptr(如果未删除或无法访问复制构造函数)。

合理的默认值都不是——统一初始化语法(自 C++11 起可用):

Foo foo{};

虽然不如名称所暗示的那么统一,但它使您的对象零初始化并且不受大多数​​令人烦恼的解析的影响。

【讨论】:

  • 这很好,但是你应该提到统一初始化语法是C++11中的一个新特性;许多编译器仍然默认使用 C++03。
【解决方案2】:

您几乎应该总是写X x;X x{};

X 是类类型时,X x;x 声明为X 类型的变量并运行默认构造函数 对其进行初始化。它可以被认为是X x(); 的简写,除了因为most vexing parse,你实际上不能 X x();

X x{}; 是 C++11 中的一个新特性。它与X x; 几乎但不完全相同。重要的区别在于,对于X x{};,默认构造函数未初始化的任何数据成员都将自动初始化为零。使用X x;,任何此类成员都将保持未初始化状态。 (对于编写良好的 C++ 类,不会有任何成员未初始化,但X x{} 对于 POD 结构很方便,例如您可能从面向纯 C 的系统头文件中获得的那些。)

X x = X(); 完全不同。形式上等价于

X __temp_0{};
X x(__temp_0);
__temp_0.~X();

除了一些无法用语言表达的范围和命名细节。它创建一个额外的X 类型的临时变量并默认初始化它。然后它使用 X 的 copy 构造函数从临时变量中初始化 x,最后销毁临时变量(运行其析构函数)。这两件事是否具有相同的效果取决于 X 的构造函数和析构函数的作用,并且通常还取决于您的 C++ 编译器在优化“抽象惩罚”方面的表现。如果X 没有可访问的隐式复制构造函数,它将根本无法编译。

【讨论】:

  • 这是相当误导的。取决于X,一个可能会留下未初始化数据成员的对象,而另一个则不会。
  • @juanchopanza X 是类类型时X x;X x(); 总是做同样的事情。他们是否给对象留下未初始化的数据成员完全取决于 X 的默认构造函数。
  • 不,他们并不总是做完全相同的事情。除非您对“类类型”有非标准定义,否则您可以详细说明以澄清答案。
  • @juanchopanza 任何用struct fooclass foo 声明的类型都是我的意思。可能我记错了什么,但我真的不这么认为。请提供对 C++ 标准的具体参考以支持您的论点。
  • 对,所以这并不完全正确。 sturct X { int n;}; 例如。对于自动存储xX x; 使 x.n 未初始化,X x = X(); 使其为零初始化(X x{}; 也是如此)
猜你喜欢
  • 1970-01-01
  • 2021-09-09
  • 2021-12-31
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2010-09-18
相关资源
最近更新 更多