c++ - 在 2018 年的 C++11 及更高版本中,helper init() 函数是否被视为错误形式?

标签 c++ c++11

在 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/

相关文章:

c++ - 有没有办法通过getter将二维数组作为成员变量返回?

c++ - 从C++连接MySQL : error LNK2001: unresolved external symbol

c++ - 将嵌套的 std::arrays 视为具有链式 .data() 的单个平面数组

C++映射错误,有结构和方法,无法将字符串转换为_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<等

c++ - 带有 boost ublas 的常数矩阵

c++ - 如何使用 boost::python 创建和使用 Python 对象的实例

python - 尽管使用 -std=c++11 调用了编译器,但为什么 std::move 未定义?

c++ - 如何根据类参数定义成员类运算符

C++ - Pthread 如何发送值

c++ - 指向成员 : works in GCC but not in VS2015 的指针