通过引用或值作为参数将共享指针传递给类

时间:2018-04-11 13:26:51

标签: c++ shared-ptr

如果要将一个共享指针传递给一个成员变量,那么共享指针是通过引用还是通过值作为参数传递给类的?

共享指针的复制将增加参考计数,并且我不想制作任何不必要的副本,因此引用计数增量。将共享指针作为参考传递解决这个问题?我认为确实如此,但是还有其他问题吗?

按值传递:

class Boo {
public: 
    Boo() { }
};

class Foo {
public:
    Foo(std::shared_ptr<Boo> boo) 
        : m_Boo(boo) {}
private:
    std::shared_ptr<Boo> m_Boo;
};

int main() {
    std::shared_ptr<Boo> boo = std::make_shared<Boo>();

    Foo foo(boo);
}

通过参考:

class Boo {
public: 
    Boo() { }
};

class Foo {
public:
    Foo(std::shared_ptr<Boo>& boo) 
        : m_Boo(boo) {}
private:
    std::shared_ptr<Boo> m_Boo;
};

int main() {
    std::shared_ptr<Boo> boo = std::make_shared<Boo>();

    Foo foo(boo);
}

2 个答案:

答案 0 :(得分:17)

按值传递,然后将其移动到成员中:

class Foo {
public:
    Foo(std::shared_ptr<Boo> boo) 
        : m_Boo(std::move(boo)) {}
private:
    std::shared_ptr<Boo> m_Boo;
};

这在所有情况下都是最有效的 - 如果调用者有一个rvalue-reference,那么就不会有一个add-ref,如果调用者有一个值,那么它将是一个add-ref。< / p>

如果您经过const&,即使在没有必要的情况下,您也会强制使用add-ref。如果您按值传递,然后在没有std::move的情况下设置,则可能会获得2个add-ref。

编辑:如果您的某个类的移动比副本便宜得多,并且您有一个函数调用,它将始终复制传入的实例,这是一个很好的模式 - 就像在这种情况下一样。您可以通过按值取值来强制复制在函数调用边界处,然后如果调用者具有右值引用,则根本不需要复制 - 它将被移动而不是。

答案 1 :(得分:-3)

在传递给函数时,应该像处理其他类一样处理shared_ptr。 在这种情况下,您应该传递给const引用。

为什么我写了为什么我写了Herb Sutter跳到分钟21:50 https://www.youtube.com/watch?v=xnqTKD8uD64