我这样做:
MyClass a=b;
使用复制构造函数初始化a
,而不涉及=
操作符重载,对吗?
如果a
已经初始化,那么=
操作符将被使用,然后我稍后将其赋值给其他东西。
I saw this:
S(std::initializer_list<T> l) : v(l) {
使用:S<int> s = {1, 2, 3, 4, 5}; // direct list-initialization
这很有趣。它是初始化的,并且使用=
操作符,但是它调用的构造函数不是复制构造函数。为什么不采用这样的语法呢?
S<int> s {1, 2, 3, 4, 5};
这就是std::vector
构造函数与std::initializer_list
的工作原理。当操作符不调用复制构造时,使用=
操作符初始化对象似乎令人困惑,不是吗?
使用复制构造函数初始化a,不涉及=操作符重载,对吗?
。
为什么不采用这样的语法:[…]
您可以使用这两种形式,它们基本上是等效的,除了使用=
的形式称为copy-list-initialization,并且它需要一个非explicit
构造函数(感谢Nicol Bolas的更正)。
=
的形式称为direct-list-initialization,它通过从初始化器直接构造对象(将初始化器作为参数传递给要初始化的对象的构造器)来(非常直观地)工作。构造函数是否为explicit
与此无关。
所以简而言之,这两种形式是等价的,除了如果构造函数是explicit
, copy-list-initialization将不起作用。如果不是这样的话,选择哪种形式主要是风格问题。
MyClass a=b;
只有在b
是MyClass
类型时才使用复制构造函数。
如果b
是OtherClass
,您将需要另一个构造函数,它不是复制构造函数,只是另一个自定义构造函数,将OtherClass
作为参数(或者更可能是const OtherClass&
,但这与问题无关-只是防止挑剔者:)。
与initializer_list
的示例相同:它是S
类型的普通构造函数,它将初始化列表作为参数。在这个意义上,它与假设的构造函数S(int n)
没有什么不同。
如果你有:
S(int n) : v(n) {} // ctor taking an int
你可以创建一个这样的实例:
S s = 4;