使用委托构造函数重新初始化

re-initialise using delegating constructor

我有这个 class X,使用委托构造函数我只想将值 ij 更改为 0。是否可以这样做?

class X{
public:
    X() = default; 
    X(int ival, int jval) : i{ ival }, j{ jval } {} 
    X(int new_i) : i{ new_i }, X(i, 0) {}    //error here


private:
    int i; 
    int j; 
};

int main()
{
    X x{ 345, 54 };

    x = X{ 34 };  //annoymous copy changes only the i:member
    return 0; 
}

编辑:我知道 X(int new_int) : X{new_int, 0} 会起作用,但我想知道如果在列表中再初始化一个变量会出现什么错误。

可能是我有另一个 z,我想将其与 ij 一起初始化。

X(int new_i) :z{ new_i }, X(new_i, 0) {}

你为什么不这样做?

X(int new_i) :X(new_i, 0){...}

这样,您将第 j 个值设置为 0,并且只有 x 个变量。

您不能在初始化列表中有一个委托构造函数另一个成员初始化器。这是不允许的,因为初始化的顺序不可能是成员声明的顺序,而是一些变量会被初始化两次,这可能是错误定义的。

如果您的示例被允许,那么有问题的构造函数将首先初始化 i<-new_i,然后 i<--i,然后 j<--0。对于非 const int,这可能是可行的,但对于更通用的类型则不然。


通过委托简单地初始化对象:

class X
{
public:
  X() = default; 
  X(int ival, int jval) : i{ival}, j{jval} {} 
  X(int ival) : X(ival, 0) {}    
private:
  int i; 
  int j; 
};

虽然在这种情况下,最好使用默认参数:

class X
{
public:
  X() = default; 
  X(int ival, int jval=0) : i{ival}, j{jval} {} 
private:
  int i; 
  int j; 
};

您还应该考虑对单参数构造函数使用 explicit 关键字以避免令人不快的意外......如

void foo(X);
foo(1);       // calls foo(X(1));

只需使用

X(int new_i) :  X(new_i, 0) {}

来自 C++ 草案标准 N3337(强调我的):

12.6.2 Initializing bases and members

6 A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-decltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class, it shall be the only mem-initializer;