【问题标题】:Verify at compile time that objects are created as shared_ptr在编译时验证对象是否创建为 shared_ptr
【发布时间】:2019-05-25 18:35:21
【问题描述】:

我编写了一些类(通常作为boost::asio 的一部分),其对象依赖于包装在shared_ptr 中,因为它们使用shared_from_this()。如果对象没有在shared_ptr 中实例化,有没有办法阻止它被编译?

那么,我在寻找什么:

std::shared_ptr<MyClass> a = std::make_shared<MyClass>(); // should compile fine
std::unique_ptr<MyClass> a = std::make_unique<MyClass>(); // compile error
MyClass a; // compile error

【问题讨论】:

  • 我赞同 LRiO 所说的。一般来说,如果对象包含在 shared_ptr 中、堆中、堆栈中、指针中、向量中或作为数据成员,则最好(如果可能)不要自我感知,或作为一个全球性的。一旦他们意识到自己是如何进行生命周期管理的,他们就会变得更加受限。没必要这样。 shared_from_this (可以说)是一种反模式。但是...有时它可能是必要的反模式。
  • 哎呀,特别是不能使用唯一的指针。
  • 您可以使用自定义删除器在 ctor 中将拥有的 smart 初始化为此,然后再将其武装起来。
  • 它是基类还是最终类?它可以用作另一个对象(另一个等)的成员,还是容器的元素、另一个对象的成员,只要该对象具有动态生命周期并由智能指针管理?
  • @TimRandall 不允许使用唯一的智能指针是希望允许客户端使用弱指针的结果。

标签: c++ c++11 boost-asio shared-ptr typetraits


【解决方案1】:

将其构造函数设为私有,并为其提供一个静态工厂成员函数,该函数创建一个shared_ptr。不要忘记在评论中记录您的设计决定!

// Thing that foos the bar
struct Foo : std::enable_shared_from_this<Foo>
{
   // Returns a shared_ptr referring to a new instance of Foo
   static std::shared_ptr<Foo> CreateShared()
   {
      return std::shared_ptr<Foo>(new Foo);
   }

private:
   // To avoid bugs due to the shared_from_this base,
   // we restrict Foo creation to being via CreateShared().
   Foo() = default;
};

(我无法想象 std::make_shared 会因为私人 ctor 而起作用,但你可以试试。)

不过,我不得不说,这听起来不像是一个班级应该负责的事情。这是一种倒退编程。

盗取Eljaywords

一般来说,如果对象包含在 shared_ptr 中、堆中、堆栈中、指针中、向量中或作为数据成员,或作为全局成员。一旦他们意识到自己是如何进行生命周期管理的,他们就会变得更加受限。没必要这样。 shared_from_this(可以说)是一种反模式。但是...有时它可能是必要的反模式。

我宁愿避免使用enable_shared_from_this,并让人们使用您认为合适的Foo,例如通过精益的unique_ptr

【讨论】:

  • 如果你想共享,添加一个私有令牌类型struct private_ctor_t { explicit private_ctor_t(int){} }; 和一个以private_ctor_t 作为其第一个参数的public ctor。然后拨打make_shared&lt;Foo&gt;(private_ctor_t(0))
  • @Yakk-AdamNevraumont 假设。嗯。好像有点漏由于无法做到make_unique 的影响仅限于CreateShared impl,我想我更喜欢它是怎样的 tbh
  • @light 你误会了我想;私有 ctor 类型是私有的。调用公共 ctor 的唯一方法是使用私有 ctor 类型实例。获得它的唯一方法是成为朋友、会员将其传递给您。基本上,它允许传递令牌以使 in create shared 共享,从而节省内存分配并改善局部性。这是关于 make_shared,而不是 make_unique。
  • @Yakk-AdamNevraumont 哦,对,这比我想象的要好。公共 ctor 拿了一些你自己不能创造的东西仍然感觉有点漏,但我可以接受 ^_^ 它是否改善了局部性?它所改变的只是构造方法,在这种情况下(内置类型 args),这是否真的有目的?
猜你喜欢
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
相关资源
最近更新 更多