为什么我们需要传递const共享指针作为引用?

时间:2019-08-07 01:43:38

标签: c++ c++11 shared-ptr smart-pointers

当我阅读开放源代码时,我发现以下内容,其中共享指针以两种不同的方式传递给函数。

class A{A();};

typedef std::shared_ptr<A> A_Ptr;

void func1(A_Ptr a);

void func2( const A_Ptr& a);

使用const时将其作为参考传递的原因是什么?我了解func2的作者并不希望该功能能够更改a中的任何内容。但是我们不能只做const A_Ptr a吗?另外,我们不应该在func1中将A_Ptr & a传递给它的原因是什么?

上面代码的出现:

Git:https://github.com/uzh-rpg/rpg_svo/

List of FramePtr in the code

void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame)

void DepthFilter::addFrame(FramePtr frame)

1 个答案:

答案 0 :(得分:0)

  

但是我们不能只做这个const FramePtr框架吗?

当然可以,但是将调用复制构造函数,这对于较大的类型(大于内置类型的任何类型)通常比通过引用传递更昂贵。 shared_ptr并没有特定的含义。通常,如果您不需要副本并且不想更改它们,则默认情况下应该通过const引用传递任何对象。只能按值传递内置类型(如int,float或char)。

更有趣的是,为什么func1使用副本。最可能的情况是他仍然需要一份副本,因为他想在班级中保留一个引用。我在发布的github存储库中找不到您要引用的确切文件。如果仍不清楚,请把func1的函数体放到问题中。

编辑:嗯,我明白了。看起来他在这里按值传递的原因更多与线程安全有关。没有读取全部内容,但是如果shared_ptr被const引用传递,则可能被拥有线程删除。

这里的func需要传值,否则指针可能被主线程删除。大概是这样,但是更复杂:

#include <chrono>
#include <iostream>
#include <memory>
#include <thread>

using namespace std::chrono_literals;

struct S {
    S() {}
};

void
//This signature would be false
//func(std::shared_ptr<S> const& s)
func(std::shared_ptr<S> s)
{
    std::cout << s.use_count() << '\n';
    std::this_thread::sleep_for(2s);
    //use_count would be 0 here if we pass by reference
    std::cout << s.use_count() << '\n';
}



int
main(int argc, char**) {
    std::shared_ptr<S> s{std::make_shared<S>()};

    std::thread t{func, std::ref(s)};

    std::this_thread::sleep_for(1s);

    s.reset();

    t.join();

    return 0;
}