2

我有这个类X,使用委托构造函数我只想将值更改ij0。可以这样做吗?

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,我想用iand初始化它j

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

4

3 回答 3

2

只需使用

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

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

12.6.2 初始化基和成员

6 A可以使用任何表示构造函数类本身的构造mem-initializer-list函数委托给构造函数类的另一个构造函数。如果 a指定构造函数的类,它应该是唯一的class-or-decltypemem-initializer-idmem-initializer

于 2015-02-27T19:23:10.590 回答
1

你为什么不这样做?

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

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

于 2015-02-27T19:20:45.527 回答
1

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

如果您的示例被允许,那么有问题的构造函数将首先初始化i<- new_i,然后是i<-- i,然后是j<-- 0。对于 non- 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));
于 2015-02-27T19:23:08.660 回答