参数和成员变量在构造函数中的用法
Usage of parameter and member variable in constructor
在编写类的构造函数时,我经常问自己是否应该使用初始化的成员变量或构造函数参数。这里有两个例子来说明我的意思:
构造函数参数
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;
}
我知道这并不重要(除了一些特殊情况),这就是为什么我宁愿征求对代码设计的评论,而不是什么让它工作,什么不工作。
如果您需要一个特定的问题来处理:什么方法会产生一个漂亮且一致的代码设计,并且一个比另一个有(缺点)优势?
编辑:不要忘记问题的第二部分。构造函数体中的变量呢?
我会使用 Constructor 参数,因为在使用该初始值设定项时,这些初始值设定项的执行顺序由声明成员的顺序决定,而不是它们的列出顺序。 所以,在这里要小心。
我个人更喜欢使用构造函数参数,以避免使用尚未初始化的成员变量。
事实上,在这个例子中:
class Foo {
private:
int mEntity;
int mSpeed;
public:
Foo(int speed) :
mSpeed(speed),
mEntity(mSpeed)
{ }
}
mEntity 的初始化将在 mSpeed 初始化之前进行(因为它是在之前声明的)。因此,您将使用未初始化的 mSpeed 初始化 mEntity。
--
在构造函数主体本身内部,我也会使用构造函数参数,因为在调试时看到您使用速度来初始化 mMonster 而不是本身用速度初始化的 mSpeed 会更直接一些。当然,这是一个简约的开销,但由于我们可以轻松避免它,我认为最好这样做。
我更喜欢在必须固定参数的情况下使用成员变量:
class Foo {
public:
Foo(int speed) :
mSpeed((speed < 0 ? 0 : speed)),
mEntity(mSpeed)
{ }
}
这样,如果参数无效,则不会用于导致后续成员也无效。
否则,我坚持使用参数变量。
我会使用构造函数参数。为什么?因为这个问题。构造器参数清晰易读,您无需了解太多C++即可知道会发生什么。如果您对C++了解不够,使用成员很容易出错,并且即使您做得对,也会使团队中没有您知识水平的其他人感到困惑。
如有疑问,请保持简单。
你绝对应该使用构造函数参数。如前所述,成员变量将按照它们在头文件中声明的顺序进行初始化,而不是按照它们在初始化列表中出现的顺序进行初始化。
如果顺序不匹配,一些编译器会警告您,但使用构造函数参数只会让您少担心一件事。例如,在编辑类界面时,很容易以这种方式引入错误。使用成员变量初始化其他成员变量没有任何好处。
我也会使用构造函数参数。请参阅简单示例:
// 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.
{}
因此,如果您使用成员而不是构造函数参数,则可能很容易创建错误情况。
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 构造函数的用法
- 使用指针复制构造函数用法
- CPP/C 中的常量用法和结构构造函数中的澄清
- 复制构造函数方法的用法
- 参数和成员变量在构造函数中的用法
- C 中的构造函数和破坏者的内联用法
- 为什么内存泄漏只发生在赋值运算符重载的情况下,而不是在复制构造函数中,以及复制和交换习惯用法如何解决它
- 使用检测习惯用法来确定类型是否具有具有特定签名的构造函数
- C++:复制和交换习惯用法,替代构造函数
- 带有智能指针的虚拟构造函数习惯用法
- 如何实现拷贝交换习惯用法的复制构造函数
- 对象构造函数"settings"习惯用法
- c++单例用法:编译器抱怨私有构造函数
- 移动构造函数的预期用法未发生
- const char*在构造函数中的用法