为什么复制初始化是这样的?为什么需要复制构造函数?

8
可能是重复问题: 为什么复制初始化和直接初始化的行为不同? 通过复制初始化,我指的是这样:
struct MyStruct
{
    MyStruct(int) {}
    MyStruct(const MyStruct&) {}
};

MyStruct s = 5; // needs *both* the int and copy constructor

尽管我已经使用C++编程多年,但我从未意识到上述代码需要复制构造函数(感谢jogojapan)。该临时变量总是被省略掉的,因此我甚至不知道它的存在(至少在表面上,尽管它被优化了),直到有人指出这一点。
通过大量谷歌搜索,我知道了它的工作原理。我的问题是,为什么它是这个样子?
为什么标准没有将上述示例设计成不需要复制构造函数?是否有某些特定的情况或示例说明在此类型的初始化中需要复制构造函数?
如果没有一个合理的解释说明为什么会是这样,我只会把它看作是一个烦人的遗产,但如果有一些重要的东西我不知道,我宁愿不要无知。

似乎复制构造函数只是为了名义而存在;实际上它并没有被调用。 - iammilind
@iammilind:它不必被称为由于复制省略,但是复制构造函数需要可访问。基本上,这意味着标准允许调用复制构造函数并且它必须可用。优化并非标准保证的事实上相反,标准是为其提供容纳空间的。 - Alok Save
1
@JesseGood:谢谢你。看起来这几乎是一个重复的问题。有点令人沮丧的是在那个问题上没有一个好的答案... - Cornstalks
@Cornstalks:实际上,我认为得票最高的答案是正确的:“之所以设计成这样,是因为程序员预计会期望这种行为。”如果我没记错的话,我们之所以有 MyStruct s = 5; 这样的语法(使用 =)是因为很多人习惯了它。 - Jesse Good
1
@JesseGood:我想这是有道理的。我认为将之前的解释与“MyStruct s = 5;实际上被转换为MyStruct s = MyStruct(5);以将5转换为MyStruct”的解释结合起来,可以作为一个合理的解释。 - Cornstalks
1个回答

0

对象的复制初始化与直接初始化存在歧义,两者都可以同样使用以将值设置为相等。

int a = 4;
int a = int(4);
int a(4);

所有这些调用都是模糊的,它们都将a设置为4。在整数的情况下使用复制构造函数的原因是方便,想象一下没有这个功能的C++数据类型。

int a(foo(b,r)); //a little messy for a variable declaration
int a = foo(b,r) //ok, cleaner

你也可能需要使用隐式和显式的复制构造函数,这里有一个示例程序,它显式地使用复制构造函数来处理虚数:

#include <iostream>
using std::cout;
using std::endl;
class complexNumbers {
  double real, img;
public:
  complexNumbers() : real(0), img(0) { }
  complexNumbers(const complexNumbers& c) { real = c.real; img = c.img; }
  explicit complexNumbers( double r, double i = 0.0) { real = r; img = i; }
  friend void display(complexNumbers cx);
};
void display(complexNumbers cx){
  cout<<&quot;Real Part: &quot;<<cx.real<<&quot; Imag Part: &quot;<<cx.img<<endl;
}
int main() {
  complexNumbers one(1);
  display(one);
  complexNumbers two =2;
  display(200);
  return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接