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

std::shared_ptr - Best practice for passing shared pointer as parameter

我离开认真的C ++已有十年了。 我将回到正题,目前正在致力于使C ++ 11完全熟悉的项目。 我在如何最好地传递std :: shared_ptr周围存在一些生存危机。

举一个简单的例子,进行以下设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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的常见"最佳实践"是什么?


您应该完全像绕过其他对象一样绕过共享指针。如果需要存储(共享指针的副本,而不是指向对象的指针的)副本,请按值传递,然后移至其目的地。

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

另外,如果您不介意编写两个构造函数,则可以编写一个采用const引用并复制它的实例,而使用一个r-作为实例,从而节省一点性能(一次调用共享指针的move构造函数)。值参考,并将其移动。

1
2
3
4
5
ServiceA(std::shared_ptr<ServiceB> const& serviceB)
    : _serviceB(serviceB) {}

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


当您打算修改实际参数时,按引用传递给非常量。

当您不希望通过引用传递给const时。

从技术上讲,对const的引用只是对shared_ptr的微优化,但这没有害处,它是类类型参数的通用约定,并且可以节省几纳秒的时间。

另一回事,由于C为实现名称使用前缀下划线,因此最好避免在C ++中使用,因此,不要在字符串前加下划线。例如那是boost库中的约定。或者只是使用其他约定。


要么按值传递(编译器非常擅长复制副本),要么按const引用-非const引用,因为这使您看起来好像打算修改参数。

同样对于新代码,请考虑在参数有意义的地方或共享不属于合同的范围内,对参数和返回值使用unique_ptr。 (您可以从unique_ptr生成shared_ptr,反之亦然。)