我已使用以下方法声明了序列化类,但尚未实现:
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通过引用?
答案 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)
node
是weak_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();
就是那个意思。