【问题标题】:C++ hidden constructor for objects managed by shared_ptr由 shared_ptr 管理的对象的 C++ 隐藏构造函数
【发布时间】:2013-02-10 22:29:25
【问题描述】:

我有一个继承自 enable_shared_from_this 的类。它对子对象有shared_ptrs,并且有一个“根”对象,因此整个层次结构由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()?

【问题讨论】:

  • 你似乎很清楚地了解了利弊。如果类需要shared_ptr管理,我会隐藏构造函数。
  • @DrewDormann 在我的用例中,所有对象都在层次结构中,但总的来说,我不知道。唯一的判断方法是共享内存和对象的经验,而我没有。像 gtkmm 这样的库隐藏了 ctor - 等等,我想我明白了!隐藏 ctor 有一个很好的理由:防止用户在共享对象上意外调用 delete。对于隐藏的 ctor,只有在显式调用 shared_ptr::get() 时才会发生 :)
  • 但还有一个问题:将 create() 设为公开还是将用户限制为 add_child()?
  • @fr33domlover 如果你想阻止用户删除,你隐藏析构函数,而不是构造函数。 (然后您必须在创建时将其传递给 shared_ptr,这会迫使您提供一个函数来创建所述指针)。
  • “然后你必须在创建时将 [dtor] 传递给 shared_ptr”......他说你可以将“删除”函数传递给 shared_ptr 构造函数。 en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

标签: c++ c++11 constructor shared-ptr


【解决方案1】:

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

当然,如果所有人都安全,您可以将这三个人都公开。否则,通过将不安全的部分设为私有(或者可能是受保护的,如果它是要派生的类的构造函数)来隐藏不安全的部分,并将安全的部分公开以供用户使用。

【讨论】:

    猜你喜欢
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多