何时使用weak_ptr而不是通过引用进行调用

时间:2019-06-12 18:08:43

标签: c++ c++11 c++14

我已使用以下方法声明了序列化类,但尚未实现:

    const std::string toJson(const Location &obj);

    const std::string toJson(std::weak_ptr<const Location> obj);

    const std::string toJson(std::shared_ptr<const Location> obj);

毫无疑问,序列化类的工作是在一种表示形式之间转换,例如从Json到C ++类,反之亦然。

现在在代码中的其他地方,我拥有这样的独特所有权:

    std::unique_ptr<Location> uniqueLocation = getLocation();

现在我的问题是:序列化不需要取得unique_ptr的所有权。应该调用哪种方法? toJson使用weak_ptr,还是toJson通过引用?

3 个答案:

答案 0 :(得分:4)

您无法从std::shared_ptr创建std:::unique_ptr(除非您首先拥有release()的所有权),也不能从{{ 1}},仅来自std::weak_ptr。这样就只剩下一个选择:

std::unique_ptr

这很有意义,因为您不需要或不想std::shared_ptr来获得/共享const std::string toJson(const Location &obj);对象的所有权,而只是按原样使用它即可。

说实话,其他重载根本没有多大意义。调用者应决定如何获取对toJson()对象的引用,然后根据需要将实际对象传递给Location,例如:

Location

但是,如果要保留重载,只需让它们委托给一个采用对象引用的重载即可:

toJson()

答案 1 :(得分:3)

nodeweak_ptr的伴侣,在这里无济于事。

您可以使用第一个重载,也可以通过引用传递shared_ptr本身。

即使您使用的是unique_ptr而不是shared_ptr,我也建议您这样做。我之前将unique_ptr s存储在容器中(或在lambda中捕获了它们),但是如果您只是传递给需要做一些工作的函数,那么这似乎是不必要的开销。

Herb's opinion on the subject可能会让您感兴趣。

答案 2 :(得分:0)

智能指针与所有权有关。

所有权是终身的。

const std::string toJson(const Location &obj);

这表示“您将传递一个有效的obj的{​​{1}},并且此函数承诺不会对其进行更改”。

返回值Location是有毒的反模式。不要那样做返回const std::string

std::string

这说明“我将忠实地存储在std::string toJson(std::weak_ptr<const Location> obj); 的引用中,并将其忠实地存储在某个地方。在某个未知的将来,我将检查该对象是否仍然存在,并创建一个指向它的共享指针。一旦调用此函数,就不要假设指向obj的指针的寿命将在任何受控位置结束;但是通常我会很有礼貌,并且不坚持使用生成的obj比一小段。”

shared_ptr

这说:“我想参与指向std::string toJson(std::shared_ptr<const Location> obj); 的共享管理。obj具有并且应该具有复杂的生存期,无法通过简单的所有权轻易表达。我试图使用更简单的方法所有权模型,但是它们并不能反映obj可以生存多长时间的真正本质,因此我使用的是引用计数指针。”

obj

这说:“我想控制这个对象的所有权,从来没有遇到过复杂的所有权情况。如果可以的话,我会是一个价值(或者可能是可选的),但是有些问题使我无法成为一个值。因此,我将成为一个唯一的指向值的指针。“

  

序列化不需要获得unique_ptr的所有权。应该调用哪种方法? toJson使用weak_ptr,还是toJson通过引用?

将事物转换为Json的函数可能只需要转换的对象在调用的长度内才有效。

std::unique_ptr<Location> uniqueLocation = getLocation(); 就是那个意思。