在编写类的构造函数时,我经常问自己是否应该使用初始化成员变量或构造函数参数。这里有两个例子来说明我的意思:
构造函数参数
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)优势而不是另一个?
编辑:不要忘记问题的第二部分。那么构造函数体中的变量呢?
答案 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参数,则可能很容易创建错误情况。