为什么使用初始化方法而不是构造函数?

新手上路,请多包涵

我刚进入一家新公司,大部分代码库使用初始化方法而不是构造函数。

 struct MyFancyClass : theUberClass
{
    MyFancyClass();
    ~MyFancyClass();
    resultType initMyFancyClass(fancyArgument arg1, classyArgument arg2,
                                redundantArgument arg3=TODO);
    // several fancy methods...
};

他们告诉我,这与时间安排有关。有些事情必须 构造函数中失败的构造之后完成。但是大多数构造函数都是空的,我真的看不出有什么理由不使用构造函数。

所以我转向你,哦 C++ 的巫师:你为什么要使用 init 方法而不是构造函数?

原文由 bastibe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 733
2 个回答

既然他们说“计时”,我想这是因为他们希望他们的 init 函数能够调用对象上的虚函数。这并不总是在构造函数中起作用,因为在基类的构造函数中,对象的派生类部分“还不存在”,特别是您无法访问派生类中定义的虚函数。而是调用函数的基类版本(如果已定义)。如果它没有被定义,(暗示这个函数是纯虚拟的),你会得到未定义的行为。

使用 init 函数的另一个常见原因是希望避免异常,但这是一种相当老派的编程风格(而且它是否是一个好主意是它自己的一个完整的论点)。它与无法在构造函数中工作的事物无关,而是与构造函数在失败时无法返回错误值的事实有关。所以就你的同事给你的真实原因而言,我怀疑不是这样。

原文由 Steve Jessop 发布,翻译遵循 CC BY-SA 2.5 许可协议

另一个用例:

你有一个对象池,就像一个简单的对象向量(不是指针向量,而是实际堆栈分配的对象紧密打包)。

对象类很复杂,有很多私有成员变量,都需要正确设置。

因此,每个对象在插入时都会正确构造(使用构造函数,带有许多参数)。

到目前为止,init 函数还没有出现在图片中,构造函数可以做到这一点。

由于外部事件,中间的对象之一必须是:

  • 从池中移除,基本销毁
  • 并且必须使用不同的参数创建一个新元素。

您不想对单个元素进行内存操作,例如 delete/new 来调用构造函数/析构函数,这很昂贵。您想要的是使用新参数完全处理和重新初始化现有对象,因此不会发生重新分配。

这可以通过每个变量的 getter setter 函数来完成,但这并没有处理 dispose 部分,也很容易从列表中遗漏成员变量,并且您最终会部分设置对象。最好将一个 init 函数放在一起,该函数需要其成员变量的所有必要参数,并在需要时一遍又一遍地简单地重新初始化整个对象。

原文由 Avi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题