5

考虑以下 C++ 类:

struct Point
{
    int x;
    int y;

    explicit Point() =default; // 1
    explicit Point(int x_, int y_): x(x_), y(y_) { } // 2
};

第二个构造函数对于创建Point具有特定xy值的 a 很有用。第一个存在以便我可以默认构造一个Point. 然而,为了效率,它被编辑并且default不设置为零。如果我确实想将所有成员设置为零,我可以有另一个构造函数:xy

explicit Point(int val) : x(val), y(val) { } // 3

这样,我可以选择默认初始化Point,或者在所有成员设置为零的情况下对其进行初始化:

Point p1;    // Don't initialize members.
Point p2(0); // Initialize all members to zero.

第三个构造函数的问题是我真的可以传递任何值,而不仅仅是零。例如:

Point p(1); // Both x and y set to 1! Is this the intent? If so,
            // probably should have used Point p(1, 1) instead.

另一种方法是使用表示零或默认值的特殊类型并将其传递给构造函数:

explicit Point(Default) : x(0), y(0) { } // 4

其中Default可以简单定义为:

struct Default { };

然后,我可以控制何时Point使用默认值进行初始化:

Point p1;            // Don't initialize members.
Point p2(Default()); // Initialize members with default values.

哪种方法会被认为更好,具有哨兵类型的方法Default(第 4 号),还是采用单个值并将所有成员初始化为该值的构造函数(第 3 号)?这两种方法的优缺点是什么?还是有另一种更好的机制来做到这一点?

编辑:请注意,选择这个简单的类是为了说明;实际上,可能有更多成员需要特定的默认值才能被视为“已初始化”

4

3 回答 3

11

Make your life easier, make simple data structs like this aggregates:

struct Point
{
    int x;
    int y;
};

Now you can use aggregate initialization:

Point p;      // members uninitialized
Point p{};    // members set to 0
Point p{1,2}; // members set to 1,2
于 2016-12-04T18:59:39.273 回答
2

我看到的最常见的做法是使用初始化列表实现无参数构造函数,该初始化列表包含设置为您想要的任何默认值的类的每个成员。

Point(): x(0), y(0) { }

The reasoning behind this is that you probably never want to instantiate an object without initializing the members to some known value, so you don't actually want that default constructor to exist.

于 2016-12-04T18:58:44.520 回答
0

Another option is to use:

struct Point
{
    int x;
    int y;

    explicit Point(int x_ = 0, int y_ = 0): x(x_), y(y_) {}
};

Point p1;        // 0, 0
Point p2(1);     // 1, 0
Point p3(1, 10); // 1, 10
于 2016-12-04T19:15:36.900 回答