为什么不允许其他构造函数?

时间:2016-09-28 09:12:55

标签: c++ initializer-list

我正在学习初始化列表,并了解到const成员必须使用它进行初始化,因为您无法使用默认构造函数或参数化构造函数对其进行初始化。

class Foo
{
private:
    const int y;            
public:         
    Foo(int yy) :y(yy){}        
    int getY();
};

现在假设我有另一个成员int x; 不是const,为什么我不能使用默认构造函数对其进行初始化,这个限制背后的想法是什么?

提供错误的代码:

class Foo
{
private:
    const int y;    
    int x;
public:     
    Foo(int yy) :y(yy){}
    Foo()
    {
        x = 100;
    }
    int getY();
};

3 个答案:

答案 0 :(得分:4)

  

我正在学习初始化列表,并了解到const成员必须使用它进行初始化,因为你无法使用默认构造函数或参数化构造函数初始化它。

可以在默认构造函数和任何参数化构造函数的成员初始值设定项列表中初始化Const成员。 (默认构造函数是可以在没有参数的情况下调用的构造函数。)

  

现在假设我有另一个成员int x;不是const,为什么不能使用默认构造函数初始化它,这个限制背后的想法是什么?

您可以在默认构造函数中初始化任意数量的成员(可能有一些实现定义的限制,但它与此问题无关)。您没有描述这样的限制。

Demo,包含两个成员的类,都在默认构造函数中初始化:

struct Foo {
    const int y;
    int       x;
    Foo(): y(1), x(100){}
};

编辑mcve。

  

提供错误的代码:

class Foo
{
private:
    const int y;    
    int x;
public:     
    Foo(int yy) :y(yy){}
    Foo()
    {
        x = 100;
    }
    int getY();
};

所有构造函数必须初始化const成员。您的参数化构造函数会初始化y,但默认构造函数不会。这就是为什么它不起作用。有关工作示例,请参阅上面的演示。

PS。你的参数化构造函数没有初始化x,但没关系:x不是常量,所以你可以稍后为它赋值。

  

在我的代码中,如果我有一个参数化的构造函数,如Foo(int xx){x = xx;}

     

它不会给出任何错误

这个程序:

struct Foo {
    const int y;
    int       x;
    Foo(int xx) { x = xx;}
};

在标准C ++中生成错误。如果您的编译器在没有警告的情况下接受它,那么它就不符合标准。

答案 1 :(得分:1)

不清楚你想要完成什么。 以下代码只是编译

class Foo
{
private:
    int _nonConst;
    const int _const;

public:
    Foo() : _const(10), _nonConst(11)
    {

    }

    Foo(int x) : _const(x), _nonConst(x)
    {

    }
};

答案 2 :(得分:0)

我不确定我是否正确理解了这个问题。总结一下你能做什么和不能做什么:

// .h
class MyClass
{
private:
    int x;
    const int y;

public:
    MyClass();
    MyClass(int initValue);
};

// .cpp
// The following is legal
MyClass::MyClass() 
: x(0), y(0) 
{}     

// Alternatively, the following is legal too. 
MyClass::MyClass() 
: y(0) 
{ 
    x = 0; 
}   

// This is not legal: y cannot be initialized that way as it is const.
// No problem for x though.
MyClass::MyClass() 
{ 
    x = 0; 
    y = 0; // You cannot do that
} 

// The following is legal
MyClass::MyClass(int initValue) 
: x(initValue), y(initValue) 
{}     

// Alternatively, the following is legal too. 
MyClass::MyClass(int initValue) 
: y(initValue) 
{ 
    x = initValue; 
}   

// This is not legal: y cannot be initialized that way as it is const.
// No problem for x though.
MyClass::MyClass(int initValue) 
{ 
    x = initValue; 
    y = initValue; // You cannot do that
} 

当然,每个声明的签名只能有一个CTor。上面的例子是每个声明签名的3个备选方案--2个合法的和1个非法的。