提问人:Mix Kira 提问时间:6/7/2023 最后编辑:user17732522Mix Kira 更新时间:6/7/2023 访问量:97
按值返回的临时shared_ptr的计数器是否递增?
Does a temporary shared_ptr returned by value have the counter incremented?
问:
我试图了解 RVO 在这种特殊情况下如何协同工作。shared_ptr
假设我有这个示例代码:
class A {
public:
void action() {}
};
class Container {
public:
shared_ptr<A> getA() { return m_a; }
private:
shared_ptr<A> m_a;
};
Container cont{};
cont.getA()->action();
如果我没记错的话,在这种情况下,返回的 by 不应该被复制/复制构造,因为它是由编译器优化的。
那么,在最后一行中,我调用函数的函数应该直接包含在对象内部的函数吗?shared_ptr
getA()
shared_ptr
action()
m_a
Container
在这种情况下,如果指针没有被复制,内部引用计数是否不会递增/递减?
而且因为我将它用作 r 值,所以它经过优化,我可以直接使用它来访问指向对象,而无需任何成本,就像原始指针一样?
如果不是这样,有没有办法避免增加/减少的成本?我实际上并没有保留 ,但我仅将其用于对包含的对象进行操作。shared_ptr
或者,所包含对象的生存期可能存在任何问题?
答:
getA() 返回的shared_ptr不应被复制/复制构造,因为它是由编译器优化的。
是的,它将被复制。 不是局部变量,因此无法进行NRVO(命名返回值优化),并且按值返回它确实会复制构造返回的。m_a
shared_ptr<A>
评论
简而言之。。。
#include <iostream>
struct foo {
foo() = default;
foo(const foo&) { std::cout << "copy\n";}
};
foo bar() {
foo f;
return f;
}
int main() {
foo g;
g = bar();
}
在不省略复制的情况下:你调用函数,在函数里面有 ,函数返回,被复制到返回的值中,被销毁,你现在有 ,一个 的副本。f
f
f
g
f
省略副本的想法是:将副本放在一边的一小段时间,永远不会超过 1 个对象。不制作副本的唯一效果是不制作副本,即可以跳过副作用,并且上面的代码不会打印任何内容。
就您而言,这不适用。 是会员。它不是函数局部变量。必须创建副本,因为从函数返回的对象与成员不同。m_a
是的,从函数返回的临时是副本。共享指针的引用计数在完整表达式的末尾递减。
评论
shared_ptr<A>& getA() { return m_a; }
下一个:获取 RVO 优化静态的地址
评论
shared_ptr
shared_ptr
action
shared_ptr