鉴于这样的课程:
class Foo {
public:
Foo(int);
Foo(const Foo&);
Foo& operator=(int);
private:
// ...
};
这两条线是完全相同的,还是它们之间有细微差别?
Foo f(42);
Foo f = 42;
编辑:我在原始问题中使Foo构造函数“显式”混淆了。我删除了它,但欣赏答案。
我还添加了一个复制构造函数的声明,以明确复制可能不是一个简单的操作。
我真正想知道的是,根据C ++标准,“Foo f = 42”会直接调用Foo(int)构造函数,还是会调用复制构造函数?
看起来fasih.ahmed有我想要的答案(除非是错的)。
答案 0 :(得分:19)
class Foo {
public:
Foo(explicit int);
Foo& operator=(int);
};
那是无效的。语法是
class Foo {
public:
explicit Foo(int);
Foo& operator=(int);
};
不同之处在于,当您在其前面放置显式时,转换构造函数不能用于隐式转换:
Foo f(10); // works
Foo f = 10; // doesn't work
以上内容与您在此处声明的赋值运算符无关。由于这是初始化(仅使用构造函数),因此不使用它。以下将使用赋值运算符:
Foo f;
f = 10;
并将使用Foo的默认构造函数(不带参数的构造函数)。
编辑:提问者将问题改为
的具体方式Foo f = 1; // called "copy initialization"
Foo f(1); // called "direct initialization"
是一样的。答案是它们等同于以下内容:
Foo f(Foo(1));
Foo f(1);
当且仅当采用int的转换构造函数未使用关键字explicit
声明时,否则第一个是编译器错误(参见上文)。如果仍然满足所有语义限制,并且即使复制构造函数具有副作用,也允许编译器在第一种情况中忽略传递给Foo的复制构造函数的临时(优化)。这尤其包括可见的复制构造函数。
答案 1 :(得分:7)
Foo f = 42;
此语句将为值'42'创建一个临时对象。
Foo f(42);
此语句将直接赋值,以便减少函数调用。