7

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

构造函数参数

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;
}

我知道这并不重要(除了一些特殊情况),这就是为什么我宁愿征求对代码设计的意见,而不是什么使它起作用,什么不起作用。

如果您需要处理一个特定的问题:哪种方式可以产生良好且一致的代码设计,并且其中一种方式是否具有(劣势)优势?

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

4

6 回答 6

3

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

于 2014-02-07T11:21:08.267 回答
2

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

事实上,在这个例子中:

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

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

--

在构造函数体本身内部,我也会使用构造函数参数,因为它在调试时更直接一些,可以看到您使用speed来初始化mMonster而不是本身使用speed初始化的mSpeed。当然这是一个极简的开销,但我们可以很容易地避免它,我认为这样做更好。

于 2014-02-07T11:31:16.117 回答
1

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

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

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

否则我坚持参数变量。

于 2014-02-07T11:40:03.743 回答
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.
{}

因此,如果您使用成员而不是构造函数参数,您可能很容易创建错误情况。

于 2014-02-07T16:56:36.350 回答
0

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

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

于 2014-02-07T11:25:38.853 回答
0

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

如果订单不匹配,一些编译器会警告您,但使用构造函数参数只会让您少担心一件事。例如,当您编辑类界面时,很容易以这种方式引入错误。使用成员变量来初始化其他成员变量并没有什么好处。

于 2014-02-07T11:36:33.763 回答