【问题标题】:Why is the assignment operator not called in this case in favor of the copy constructor?为什么在这种情况下不调用赋值运算符来支持复制构造函数?
【发布时间】:2013-02-01 00:37:48
【问题描述】:

来自复制构造函数的维基百科页面:

X a = X();     

// valid given X(const X& copy_from_me) but not valid given X(X& copy_from_me)
// because the second wants a non-const X&
// to create a, the compiler first creates a temporary by invoking the default constructor
// of X, then uses the copy constructor to initialize as a copy of that temporary. 
// For some compilers both versions actually work but this behaviour should not be relied 
// upon because it's non-standard.

具体部分:

" 编译器首先通过调用默认值创建一个临时 X 的构造函数,然后使用复制构造函数初始化为 那个临时的副本。 "

我的问题是(假设这是正确的)为什么会这样?从代码中,我猜编译器会在构造一个 X 后使用赋值运算符。

我猜是因为赋值发生在与初始化相同的表达式中?

另外,使用这个公式的原因是什么,而不仅仅是一个正常的初始化X a; 或者如果你想复制X a(b);

【问题讨论】:

  • T a = x; 等价于T a(T(x));
  • @GManNickG 你不是只在第二个语句中初始化 x 吗?
  • 正如大家所说,这真的是c++的语义定义。然而,这是有原因的。你想构建两次,然后复制吗?或者你想用两个可能不同的构造函数构造两次?哪个更优化?另外,看看这个:en.wikipedia.org/wiki/Copy_elision。最新标准留有余地。
  • @Raskol:我不确定我是否跟随。在第二个语句中,一个临时的T 是从x 构造的,然后a 是从那个临时的复制构造的(因此页面说复制构造函数需要是const T&,因为临时对象不绑定到非常量左值引用。在 C++11 中,非常量右值引用 T&& 也可以工作;这是一个移动构造函数)。确实没有任务。由于第一个语句完全等价,第一个语句也没有赋值。
  • @GManNickG 啊,我的错,是的,我现在明白了,T(x) 正在从 x 创建一个临时 T。谢谢。

标签: c++ oop


【解决方案1】:

因为代码是构造一个对象。这里的 = 符号是初始化,而不是分配。您只能分配给现有对象,不能分配给正在构建的对象。

【讨论】:

    【解决方案2】:

    这只是理解 C++ 语法的问题。语句X a = X(); 是一个带有初始化器的声明语句,而不是 一个赋值表达式。该语句的语法含义是声明一个X 类型的变量a,并从表达式X() 中复制初始化它。这里不涉及任何分配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 2011-01-16
      • 2011-05-21
      • 2015-05-21
      • 2016-12-20
      相关资源
      最近更新 更多