由shared_ptr管理的对象的C++隐藏构造函数

C++ hidden constructor for objects managed by shared_ptr

本文关键字:对象 C++ 隐藏 构造函数 管理 shared ptr      更新时间:2023-10-16

我有一个从enable_shared_from_this继承的类。它有shared_ptr到子对象,并且有一个"根"对象,因此整个层次结构由shared_ptr管理。通过这种方式,一个对象可以有多个父对象,并且可以安全地销毁。

我开始编写一个构造函数,然后我意识到用户应该使用std::shared_ptr来管理对象,就像我在内部所做的那样,也像我在一些现有库中看到的那样,例如gtkmm。因此,我可以做我看到其他人做的事情:隐藏构造函数,并编写一个静态成员函数create(),该函数向新对象返回一个shared_ptr。显然create()非常有用,因为如果没有它,我需要调用std::make_shared(),或者稍后调用std::shared_from_this()

但是我应该隐藏构造函数吗?为什么?我可以猜测一些很好的原因,例如,它强制用户使用shared_ptr,否则对象会被删除,所以它可以保证用户不会使用不由shared_ptr管理的"孤立"对象。它确保用户不会忘记手动创建shared_ptr,因为忘记意味着对象被删除,即使它是复制的(深度复制,而不是指针的副本),然后用户很快就会注意到这一点。

另一个有趣的选项是不使用create()静态方法,而是使用add_child()方法作为创建新对象的唯一方法。这保证了它链接到层次结构。问题是:灵活性。如果有人想单独使用一个对象,那是不可能的,除非你派生了这个类。

你会做什么/我应该做什么?隐藏/不隐藏ctor?add_child()create()

在一般情况下,没有一个正确的答案。您可以从编写所有这些方法开始:构造函数、create()和create_child(),它们都是公共的。然后,在使用接口时,最好是在测试接口时(如果可能的话,在"真实"代码中使用它之前先完成),检查不同构建选项可能的副作用、结果和便利性,并决定什么对您的特定用例是最好的,什么是安全的。

当然,如果安全的话,你可以把它们三个都公开。否则,通过将不安全的隐藏为私有的(或者可能是受保护的,如果它是要派生的类的构造函数),并将安全的保留为公共的供用户使用。