std :: shared_ptr - 将共享指针作为参数传递的最佳实践

时间:2014-01-03 17:34:51

标签: c++ c++11

我已经远离严肃的C ++大约十年了。我正在重新回到目前,我正在开展一个项目,以完全熟悉C ++ 11。关于如何最好地传递std :: shared_ptr,我有一点存在的危机。

举一个简单的例子,采取以下设置:

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

class ServiceA {
public:
    ServiceA(std::shared_ptr<ServiceB>& serviceB)
        : _serviceB(serviceB) {

    }

private:
    std::shared_ptr<ServiceB> _serviceB;
};

class Root {
public:
    Root()
        : _serviceB(std::shared_ptr<ServiceB>(new ServiceB())),
        _serviceA(std::unique_ptr<ServiceA>(new ServiceA(_serviceB))) {

    }

private:
    std::shared_ptr<ServiceB> _serviceB;
    std::unique_ptr<ServiceA> _serviceA;
};

请注意,ServiceA需要引用ServiceB。我想将该引用保存在shared_ptr中。我可以做我在这里做的事情,这只是将shared_ptr作为参考传递下去,让std :: shared_ptr复制构造函数为我工作吗?这是否正确地增加了shared_ptr上的引用计数?

如果这不是最好的方法,那么传递std :: shared_ptr的常见“最佳做法”是什么?

3 个答案:

答案 0 :(得分:13)

您应该在传递其他对象时准确传递共享指针。如果您需要存储副本(共享指针的副本,而不是指向的对象),请按值传递,然后移动到目标位置。

ServiceA(std::shared_ptr<ServiceB> serviceB)
    : _serviceB(std::move(serviceB)) {}

或者,如果你不介意编写两个构造函数,你可以通过编写一个带有const引用并复制它的一个来保存一点性能(一次调用共享指针的移动构造函数),并且一个r值参考,然后移动它。

ServiceA(std::shared_ptr<ServiceB> const& serviceB)
    : _serviceB(serviceB) {}

ServiceA(std::shared_ptr<ServiceB> && serviceB)
    : _serviceB(std::move(serviceB) {}

答案 1 :(得分:3)

通过值传递(编译器非常擅长删除副本)或者通过const引用 - 非const引用,因为它使您看起来像是要修改参数。

同样对于新代码,请考虑使用unique_ptr作为参数并在有意义的地方返回值,或者共享不属于合同的情况。 (您可以从shared_ptr制作unique_ptr,但反之亦然。)

答案 2 :(得分:2)

当您打算修改实际参数时,

通过引用传递给非const。

当你不想这样做时,通过引用传递给你。

对const的引用在技术上只是对shared_ptr的微优化,但它没有坏处,它是类类型参数的通用约定,它只能减少一些纳秒。


另一个问题,因为C使用前置下划线来实现名称,所以最好在C ++中避免使用它,所以不要在前面添加下划线,而是将它放在最后。例如这是boost库中的惯例。或者只是使用其他约定。

相关问题