在对象构造中使用“=”的效果

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 (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 对于双参数构造函数来说并不是那么普遍有用,但我不怀疑在某些情况下你会需要它。