我有一个范围内的警卫对象工厂,它会在我的范围内向我要保留的警卫返回一个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_ptr
(unique_ptr
),并免费使用第一个更易读的形式? (唯一的缺点是使用auto_ptr
;))
答案 0 :(得分:3)
很可能两者都会产生完全相同的代码:
这会将返回值绑定到常量引用 没有优化的理论开销:一个参考更多的内存,访问的附加间接 实际上:在as-if规则下开销优化。
const boost::shared_ptr<SelectorGenericGuard>& guard = factory->Create();
通过初始化变量来保存返回值
没有优化的理论开销:一举一动
实际上:复制椭圆规则下的开销优化(as-if规则的例外)。
增加了危险:只有在类型完全匹配时才可以进行优化。
boost::shared_ptr<SelectorGenericGuard> guard = factory->Create();
与2相同,但不存在类型不匹配和更短的可能性(我的首选选项):
auto guard = factory->Create();
关于auto_ptr
:
总是更喜欢unique_ptr
如果你不能意识到陷阱:移动写入副本的语义,从而导致标准算法和容器失败。考虑定义自己的不可复制版本,并在需要的地方做明确的移动。但是要将它保留在ABI之外,以便以后替换:函数参数(和异常类型)。
关于unique_ptr
:如果可以这样做,unique_ptr
优于shared_ptr
,因为减少(说:不)开销。