保持从工厂Create方法返回的shared_ptr的最佳方法

时间:2014-07-24 13:22:55

标签: c++ boost shared-ptr factory

我有一个范围内的警卫对象工厂,它会在我的范围内向我要保留的警卫返回一个shared_ptr

工厂的Create方法声明是:

virtual boost::shared_ptr<GenericGuard> Create() const = 0;

我的问题是 - 写作是否更好:

boost::shared_ptr<SelectorGenericGuard> guard = factory->Create();

或:

const boost::shared_ptr<SelectorGenericGuard>& guard = factory->Create();

第一个版本可以/可能/将创建shared_ptr的副本,因此can / may /将导致额外的参考计数器增量 - 第二个显然不太可读,我无法理解我的“默认”应该是什么 - 所有被认为是可读性的东西通常都是我最喜欢的,我想听听别人的想法。

或者我应该在这里使用auto_ptrunique_ptr),并免费使用第一个更易读的形式? (唯一的缺点是使用auto_ptr;))

1 个答案:

答案 0 :(得分:3)

很可能两者都会产生完全相同的代码:

  1. 这会将返回值绑定到常量引用 没有优化的理论开销:一个参考更多的内存,访问的附加间接 实际上:在as-if规则下开销优化

    const boost::shared_ptr<SelectorGenericGuard>& guard = factory->Create();
    
  2. 通过初始化变量来保存返回值 没有优化的理论开销:一举一动 实际上:复制椭圆规则下的开销优化(as-if规则的例外)。
    增加了危险:只有在类型完全匹配时才可以进行优化。

    boost::shared_ptr<SelectorGenericGuard> guard = factory->Create();
    
  3. 与2相同,但不存在类型不匹配和更短的可能性(我的首选选项):

    auto guard = factory->Create();
    
  4. 关于auto_ptr
    总是更喜欢unique_ptr 如果你不能意识到陷阱:移动写入副本的语义,从而导致标准算法和容器失败。考虑定义自己的不可复制版本,并在需要的地方做明确的移动。但是要将它保留在ABI之外,以便以后替换:函数参数(和异常类型)。

    关于unique_ptr:如果可以这样做,unique_ptr优于shared_ptr,因为减少(说:不)开销。