私有变量的读取时间晚于成员初始化列表?

时间:2016-05-11 10:39:52

标签: c++ initialization private

我是这堂课:

class IPianoRoll : public IControl
{
private:
    int x, y;
    int w = 30 * numStep + 1;
    int h = 8 * numSemitones + 1;
    int o = 5;

public:
    IPianoRoll(IPlugBase* pPlug, int pX, int pY) : IControl(pPlug, IRECT(pX, pY, pX + o + w + o, pY + o + h + o)) {
        x = pX;
        y = pY;
    }
}

但似乎私有变量值可用"稍后"成员初始列表。因此owh不是我的值的init,而是采用不同的值。

有没有办法预先启动私有变量?

2 个答案:

答案 0 :(得分:6)

类成员的访问说明符不相关。 相关的是它们在类声明中出现的顺序。类成员在 顺序中初始化。

依赖于类成员初始化的特定顺序是非常危险的,因为错误的重构器可以在头文件中重新排序它们,而不知道源文件依赖于特定的顺序。

您还应注意,未初始化读取未初始化变量时的行为。

答案 1 :(得分:4)

首先构造基类(如果有多个基类,则从左到右),然后按声明的顺序构造成员变量(任何成员初始化列表中的顺序)。

但是,这只是非静态成员变量的情况。通过您的示例,who是适用于该类的所有实例的常量。因此,您只需将课程更改为:

class IPianoRoll : public IControl
{
private:
    int x, y;
    static const int w = 30 * numStep + 1;
    static const int h = 8 * numSemitones + 1;
    static const int o = 5;

public:
    IPianoRoll(IPlugBase* pPlug, int pX, int pY) 
       : IControl(pPlug, IRECT(pX, pY, pX + o + w + o, pY + o + h + o)) 
       , x(pX)
       , y(pY)
    {
    }
};

一切都会好的。请注意,我已将x和y设置为成员初始化列表。

如果你想让变量变为非静态变量(以便以后可以为不同的类实例更改它们),那么我会写一些类似的东西:

class IPianoRoll : public IControl
{
private:
    int x, y;
    static const int w_default = 30 * numStep + 1;
    static const int h_default = 8 * numSemitones + 1;
    static const int o_default = 5;

    int w = w_default;
    int h = h_default;
    int o = o_default;

public:
    IPianoRoll(IPlugBase* pPlug, int pX, int pY) 
       : IControl(pPlug, IRECT(pX, pY, pX + o_default + w_default + o_default, 
                                       pY + o_default + h_default + o_default)) 
       , x(pX)
       , y(pY)
    {
    }
};