虽然我花了一段时间才习惯它,但我现在养成了让我的函数通过对 const
的左值引用而不是按值来获取共享指针参数的习惯(除非我需要修改 原始参数,当然,在这种情况下,我通过对非 const
的左值引用来获取它们):
void foo(std::shared_ptr<widget> const& pWidget)
// ^^^^^^
{
// work with pWidget...
}
这样做的好处是可以避免不必要的共享指针拷贝,这意味着线程安全地增加引用计数并可能导致不需要的开销。
现在我一直在想,采用一种有点对称的习惯来检索从函数中按值返回的共享指针是否明智,如以下代码片段的末尾所示:
struct X
{
// ...
std::shared_ptr<Widget> bar() const
{
// ...
return pWidget;
}
// ...
std::shared_ptr<Widget> pWidget;
};
// ...
// X x;
std::share_ptr<Widget> const& pWidget = x.bar();
// ^^^^^^
采用这种编码习惯有什么陷阱吗?一般来说,有什么理由让我更喜欢将返回的共享指针分配给另一个共享指针对象,而不是将其绑定(bind)到引用?
最佳答案
这只是捕获对临时对象的 const 引用是否比创建拷贝更有效的老问题的翻版。简单的答案是事实并非如此。在行中:
// std::shared_ptr<Widget> bar();
std::shared_ptr<Widget> const & pWidget = bar();
编译器需要创建一个本地未命名变量(不是临时变量),通过调用 bar()
来初始化它然后将引用绑定(bind)到它:
std::shared_ptr<Widget> __tmp = bar();
std::shared_ptr<Widget> const & pWidget = __tmp;
在大多数情况下,它会避免创建引用,而只是在函数的其余部分为原始对象添加别名,但归根结底,变量是否被调用pWidget
或 __tmp
别名不会带来任何优势。
相反,对于普通读者来说,它可能看起来像 bar()
不创建对象但产生对已存在 std::shared_ptr<Widget>
的引用,所以维护者必须找到哪里 bar()
被定义为理解是否pWidget
可以在此函数的范围之外更改。
通过绑定(bind)到 const 引用来延长生命周期是该语言中的一个奇怪特性,几乎没有实际用途(即当引用是一个基类并且您不太关心 返回的确切派生类型时)值 是,即 ScopedGuard
)。
关于c++ - 将函数返回的共享指针绑定(bind)到对 const 的左值引用是好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16319652/