在对象构造中使用“=”的效果
Effects of using "=" in object construction
另一个 C++ 问题,我想弄清楚在构造对象时使用“=”有什么影响。考虑:
class Foo {
private:
int bar;
int baz;
public:
Foo(int bar, int baz)
:bar(bar), baz(baz) {}
};
int main() {
Foo foo1{4, 2};
Foo foo2 = {4, 2};
Foo foo3 = Foo{4, 2}; // I prefer this one for aesthetic reasons.
return 0;
}
有什么区别,我应该坚持哪一个作为最佳实践?
此外,虽然我们讨论的是最佳实践主题,但我听说将 explicit
添加到构造函数是一个好主意™,因为隐式转换的行为很奇怪。所以我在 Foo
:
的构造函数中添加了 explicit
public:
explicit Foo(int bar, int baz)
:bar(bar), baz(baz) {}
突然,这个:
Foo foo2 = {4, 2};
编译失败,出现错误:
error: chosen constructor is explicit in copy-initialization
这是为什么?
What are the differences
Foo foo1{4, 2};
Direct initialization is performed in the following situations:
2) during list-initialization sequence, if no initializer-list constructors are provided and a matching constructor is accessible, and all necessary implicit conversions are non-narrowing.
Foo foo2 = {4, 2};
这是copy list initialization (6)。非直接列表初始化不考虑显式构造函数。这解释了为什么当您显式更改构造函数时程序没有编译。
copy-list-initialization (only non-explicit constructors may be called)
6) initialization of a named variable with a braced-init-list after an equals sign
Foo foo3 = Foo{4, 2};
这是临时的direct list initialization (2) of a temporary object, then copy initialization (1)。
direct-list-initialization (both explicit and non-explicit constructors are considered)
2) initialization of an unnamed temporary with a braced-init-list
Copy initialization is performed in the following situations:
2) when a named variable (automatic, static, or thread-local) of a non-reference type T is declared with the initializer consisting of an equals sign followed by an expression.
第一个最简单,这就是我喜欢它的原因。
第二个需要一个隐式构造函数,但在其他方面没问题。
第三种涉及类型的重复(违反DRY),并构造一个不必要的临时(实际上,复制可能被优化器省略,但类型必须是可复制的)。
I hear adding explicit to constructors is a Good Idea™. So I added explicit to the constructor of Foo
如果要防止隐式转换,将显式添加到单参数构造函数是个好主意。 Explicit 对于双参数构造函数来说并不是那么普遍有用,但我不怀疑在某些情况下你会需要它。
另一个 C++ 问题,我想弄清楚在构造对象时使用“=”有什么影响。考虑:
class Foo {
private:
int bar;
int baz;
public:
Foo(int bar, int baz)
:bar(bar), baz(baz) {}
};
int main() {
Foo foo1{4, 2};
Foo foo2 = {4, 2};
Foo foo3 = Foo{4, 2}; // I prefer this one for aesthetic reasons.
return 0;
}
有什么区别,我应该坚持哪一个作为最佳实践?
此外,虽然我们讨论的是最佳实践主题,但我听说将 explicit
添加到构造函数是一个好主意™,因为隐式转换的行为很奇怪。所以我在 Foo
:
explicit
public:
explicit Foo(int bar, int baz)
:bar(bar), baz(baz) {}
突然,这个:
Foo foo2 = {4, 2};
编译失败,出现错误:
error: chosen constructor is explicit in copy-initialization
这是为什么?
What are the differences
Foo foo1{4, 2};
Direct initialization is performed in the following situations:
2) during list-initialization sequence, if no initializer-list constructors are provided and a matching constructor is accessible, and all necessary implicit conversions are non-narrowing.
Foo foo2 = {4, 2};
这是copy list initialization (6)。非直接列表初始化不考虑显式构造函数。这解释了为什么当您显式更改构造函数时程序没有编译。
copy-list-initialization (only non-explicit constructors may be called)
6) initialization of a named variable with a braced-init-list after an equals sign
Foo foo3 = Foo{4, 2};
这是临时的direct list initialization (2) of a temporary object, then copy initialization (1)。
direct-list-initialization (both explicit and non-explicit constructors are considered)
2) initialization of an unnamed temporary with a braced-init-list
Copy initialization is performed in the following situations:
2) when a named variable (automatic, static, or thread-local) of a non-reference type T is declared with the initializer consisting of an equals sign followed by an expression.
第一个最简单,这就是我喜欢它的原因。
第二个需要一个隐式构造函数,但在其他方面没问题。
第三种涉及类型的重复(违反DRY),并构造一个不必要的临时(实际上,复制可能被优化器省略,但类型必须是可复制的)。
I hear adding explicit to constructors is a Good Idea™. So I added explicit to the constructor of Foo
如果要防止隐式转换,将显式添加到单参数构造函数是个好主意。 Explicit 对于双参数构造函数来说并不是那么普遍有用,但我不怀疑在某些情况下你会需要它。