在 C++11 之前,您没有非静态成员初始化,也没有构造委托(delegate),因此人们经常使用私有(private)辅助函数来帮助初始化以减少代码复制。
这是 2018 年的好代码吗?
class A {
int a1 = 0;
double a2 = 0.0;
string a3 = "";
unique_ptr<DatabaseHandle> upDBHandle;
void init(){
upDBHandle = open_database(a1, a2, a3);
}
public:
A() { init(); }
explicit A(int i):a1(i) { init(); }
explicit A(double d):a2(d) { init(); }
explicit A(std::string s):a3(std::move(s)) { init(); }
A(int i, double d, std::string s) : a1(i), a2(d), a3(std::move(s)) { init(); }
};
如何改进这段代码?
最佳答案
在我看来,您的代码很好。我尽量避免依赖细微的影响,例如构造函数初始化列表中的成员初始化顺序。它违反了 DRY - 您需要重复使用相同的顺序:在声明成员时在类主体中,以及在构造函数初始化列表中。一旦时间流逝,类变得越来越大,并且您将构造函数移到 .cpp
文件中,事情就会开始变得更加困惑。因此,我将需要访问其他成员的东西放入 init
函数中。
如果成员是const
,则不能这样做。但话又说回来,作为类的作者,您可以决定哪个成员是 const,哪个不是。请注意,不要将这与“构造,然后初始化”的反模式相混淆,因为此处 init
发生在构造函数中,而类用户是看不到的。
如果您仍然不喜欢使用 init
,我建议您不要将调用放入构造函数初始化列表中。也许对我来说一个可以接受的中间方法是将它放入类内初始化器中,并从构造函数中删除所有调用。
class A {
int a1 = 0;
double a2 = 0.0;
string a3 = "";
unique_ptr<DatabaseHandle> upDBHandle = open_database(a1, a2, a3);
// ...
关于c++ - 在 2018 年的 C++11 及更高版本中,helper init() 函数是否被视为错误形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48349823/