构造函数中参数和成员变量的用法

时间:2014-02-07 11:10:52

标签: c++ code-design

在编写类的构造函数时,我经常问自己是否应该使用初始化成员变量或构造函数参数。这里有两个例子来说明我的意思:

构造函数参数

class Foo {
public:
    Foo(int speed) :
        mSpeed(speed),
        mEntity(speed)
    { }

private:
    int mSpeed;
    Entity mEntity;
}

会员变量

class Foo {
public:
    Foo(int speed) :
        mSpeed(speed),
        mEntity(mSpeed)
    { }

private:
    int mSpeed;
    Entity mEntity;
}

更多在构造函数体中使用变量会产生同样的问题。

构造函数参数

class Foo {
public:
    Foo(int speed) :
        mSpeed(speed)
    {
        mMonster.setSpeed(speed);
    }

private:
    int mSpeed;
    Monster mMonster;
}

会员变量

class Foo {
public:
    Foo(int speed) :
        mSpeed(speed)
    {
        mMonster.setSpeed(mSpeed);
    }

private:
    int mSpeed;
    Monster mMonster;
}

我知道它并不重要(除了一些特殊情况),这就是为什么我宁愿要求对代码设计进行评论,而不是让它起作用,什么不起作用。

如果您需要一个特定的问题:以什么方式产生一个漂亮而一致的代码设计,并且一个人具有(dis)优势而不是另一个?

编辑:不要忘记问题的第二部分。那么构造函数体中的变量呢?

6 个答案:

答案 0 :(得分:3)

我会使用构造函数参数,因为在使用该初始化程序时,执行这些初始化程序的顺序取决于声明成员的顺序,而不是它们的列出顺序。所以,请小心点。

答案 1 :(得分:2)

我个人更喜欢使用构造函数参数,以避免使用未初始化的成员变量。

确实,在这个例子中:

class Foo {
private:
    int mEntity;
    int mSpeed;
public:
    Foo(int speed) :
        mSpeed(speed),
        mEntity(mSpeed)
    { }
}

mEntity的初始化将在mSpeed初始化之前发生(因为之前已声明)。因此,您将使用未初始化的mSpeed初始化mEntity。

-

在构造函数体内部,我也会使用构造函数参数,因为在调试时看到你使用 speed 初始化 mMonster 并且更简单一点不是 mSpeed ,它本身是用速度初始化的。当然这是一个简约的开销,但我们可以轻松地避免它,我认为这样做更好。

答案 2 :(得分:0)

我会使用构造函数参数。为什么?因为这个问题。 construtor参数清晰可读,您不需要了解很多关于C ++的知识就知道会发生什么。如果你对C ++知之甚少,并且让你团队中其他人没有你的知识水平,即使你做得对,也容易使用会员。

如果有疑问,请保持简单。

答案 3 :(得分:0)

你绝对应该使用构造函数参数。如上所述,成员变量将按照它们在头文件中声明的顺序进行初始化,而不是按照它们在初始化列表中出现的顺序进行初始化。

如果订单不匹配,某些编译器会发出警告,但使用构造函数参数只会让您少担心。例如,在编辑类接口时以这种方式引入错误很容易。使用成员变量初始化其他成员变量没有任何好处。

答案 4 :(得分:0)

我更喜欢在必须限制参数的情况下使用成员变量:

class Foo {
public:
    Foo(int speed) :
        mSpeed((speed < 0 ? 0 : speed)),
        mEntity(mSpeed)
    { }
}

这样,如果参数无效,则不会导致后续成员无效。

否则我会坚持使用参数变量。

答案 5 :(得分:0)

我也会使用构造函数参数。 见简单示例:

// foo.h

class Foo
{
    std::unique_ptr<int[]> mBuff;
    int mSize;
public:
explicit    Foo(int size);
   // other methods...
};

// foo.c
Foo::Foo(int size)
  : mSize(size) 
  , mBuff( std::make_unique<int[]>(size) ) // here using mSize is wrong, 
            // because, mSize is not initialized yet.
            // here mSize initialized after mBuff, because it's declarated after mBuff member.
{}

因此,如果您使用member而不是constructor参数,则可能很容易创建错误情况。