c – 惰性构造的shared_ptr

前端之家收集整理的这篇文章主要介绍了c – 惰性构造的shared_ptr前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:完全重新编辑,因为原来正在成为一个非结构化的混乱:)感谢所有人的输入到目前为止;我希望我在下面的文本中使用它.

我正在寻找一个懒惰创建的可共享指针.我有一个假设的大班Thing.事情很大,制作起来也很昂贵,但是虽然它们在代码中的任何地方都被使用(共享,传递,修改,存储供以后使用等),但实际上它们实际上并没有被使用,所以它们实际上是在拖延创建直到实际访问它们是可取的.因此,需要懒惰地创造,并且需要可分享.让我们调用这个封装指针包装器SharedThing.

class SharedThing {
  ...
  Thing* m_pThing;
  Thing* operator ->() {
    // ensure m_pThing is created
    ...
    // then
    return m_pThing
  );
}
...
SharedThing pThing;
...
// Myriads of obscure paths taking the pThing to all dark corners
// of the program,some paths not even touching it
...
if (condition) {
  pThing->doIt();   // last usage here
}

要求

>实际事物的实例化必须尽可能延迟;只有在首次取消引用SharedThing时才会创建事物
> SharedThing必须安全使用,因此不需要工厂方法
> SharedThing必须具有shared_ptr(like)接口
>与尚未创建的SharedThing共享必须实际共享要创建的Thing,但Thing的实例化必须再次延迟,直到需要
>使用SharedThings必须尽可能简单(最好是100%透明,就像使用实际的东西一样)
>它必须有点高效

到目前为止,我们已经提出了四种选择:

选项1

typedef std::shared_ptr<Thing> SharedThing;
SharedThing newThing() {
  return make_shared<Thing>();
}
...
// SharedThing pThing; // pThing points to nullptr,though...
SharedThing pThing(new Thing()); // much better
SharedThing pThing = newThing(); // alternative

> 0%得分;从一开始就需要一个Thing实例
> 0%得分;你可以说SharedThing pThing;但这对事情有点过分担心
> 100%得分;)
> n.a.由于第1点
> 100%得分
> 0%得分,因为创造所有的东西到处(即使没有使用)是性能的消耗,这正是我问这个问题的原因:)

第1点和第6点缺乏得分是一个杀手;没有更多的选择1.

选项2

class SharedThing: public shared_ptr<Thing> {};

并覆盖特定成员以确保在取消引用shared_ptr时,它会及时创建Thing.

>也许可以通过覆盖正确的成员来实现(取决于stl的实现),但这很快变得混乱我认为
> 100%得分
> 100%得分,虽然模仿所有的构造函数和运算符是相当一些工作
>不知道这是否可以……
> 100%得分
如果内部事情巧妙地完成,则100%得分

这个选项优于1并且可能没问题,但看起来很混乱和/或黑客……

选项3.1

class SharedThing {
  std::shared_ptr<Thing> m_pThing;
  void EnsureThingPresent() {
    if (m_pThing == nullptr) m_pThing = std::make_shared<Thing>();
  }
public:
  SharedThing(): m_pThing(nullptr) {};
  Thing* operator ->() {
    EnsureThingCreated();
    return m_pThing.get();
  }
}

并为operator *和const版本添加额外的包装方法.

> 100%得分
> 100%得分
> do-able,但必须单独创建所有接口成员
> 0%得分;当附加到nullptr’ed SharedThing(例如operator =)时,它需要首先创建Thing以便能够共享
> 100%再次得分
> 50%得分; 2个间接

这一次在4上惨遭失败,所以这一次也是关闭的.

选项3.2

class SharedThing {
  typedef unique_ptr<Thing> UniqueThing;
  shared_ptr<UniqueThing> m_pThing;
}

添加3.1中的所有其他方法

> 100%得分
> 100%得分
> do-able,但必须单独创建所有接口成员
> 100%得分
> 100%再次得分
> 25%得分?我们这里有3个间接……

除了建议的性能(但需要测试)之外,这似乎没问题.

选项4

class LazyCreatedThing {
  Thing* m_pThing;
}
typedef shared_ptr<LazyCreatedThing> SharedThing;
SharedThing makeThing() {
  return make_shared<LazyCreatedThing>();
}

添加各种运算符 – >重载使LazyCreatedThing看起来像一件事*

> 100%得分
>与上面的选项1相同的缺点
> 100%在这里毫不费力地得分
> 100%得分
> 0%得分;取消引用SharedThing会产生一个LazyCreatedThing,所以即使它可能有它的运算符 – >为了访问Thing,它永远不会被链接,导致(* pThing) – > doIt();
> 25-50%得分?我们这里有3个间接,如果我们可以使用std :: make_shared则有2个

在这里惨败5使这成为禁忌.

结论

到目前为止,最好的选择似乎是3.2;让我们看看我们还能想出什么!

猜你在找的C&C++相关文章