c – 惰性构造的shared_ptr

c – 惰性构造的shared_ptr,第1张

概述编辑:完全重新编辑,因为原来正在成为一个非结构化的混乱:)感谢所有人的输入到目前为止;我希望我在下面的文本中使用它. 题 我正在寻找一个懒惰创建的可共享指针.我有一个假设的大班Thing.事情很大,制作起来也很昂贵,但是虽然它们在代码中的任何地方都被使用(共享,传递,修改,存储供以后使用等),但实际上它们实际上并没有被使用,所以它们实际上是在拖延创建直到实际访问它们是可取的.因此,需要懒惰地创造, 编辑:完全重新编辑,因为原来正在成为一个非结构化的混乱:)感谢所有人的输入到目前为止;我希望我在下面的文本中使用它.

我正在寻找一个懒惰创建的可共享指针.我有一个假设的大班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 betterSharedThing 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 – 惰性构造的shared_ptr全部内容,希望文章能够帮你解决c – 惰性构造的shared_ptr所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1240448.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存