假设我有一个由管理的对象std::unique_ptr
。我代码的其他部分需要访问此对象。传递指针的正确解决方案是什么?我应该只传递普通指针,std::unique_ptr::get
还是应该完全使用和std::shared_ptr
而不是std::unique_ptr
?
我有一些偏爱,std::unique_ptr
因为该指针的所有者实际上负责清理。如果我使用共享指针,则即使共享对象实际被销毁,对象也可能会保持活动状态。
编辑:不幸的是,我忘了提到指针将不仅是函数调用的参数,而且还将存储在其他对象中以建立对象的网络结构。我不喜欢共享指针,因为这样一来,谁才真正拥有该对象就不再清楚了。
如果未转移托管对象的所有权(并且由于它是unique_ptr
,则不能共享所有权),那么将调用函数中的逻辑与所有权概念分开是更正确的。我们通过引用进行呼叫。
这是一个令人费解的说法:
鉴于:
std::unique_ptr<Thing> thing_ptr;
改变事物:
// declaration
void doSomethingWith(Thing& thing);
// called like this
doSomethingWith(*thing_ptr);
使用事物而不修改它。
// declaration
void doSomethingWith(const Thing& thing);
// called like this
doSomethingWith(*thing_ptr);
您唯一要unique_ptr
在函数签名中提及的是,如果您要转移所有权:
// declaration
void takeMyThing(std::unique_ptr<Thing> p);
// call site
takeMyThing(std::move(thing_ptr));
您永远不需要这样做:
void useMyThing(const std::unique_ptr<Thing>& p);
之所以认为这是个坏主意,是因为如果将useMyThing的逻辑与所有权概念混淆,从而缩小了重用范围。
考虑:
useMyThing(const Thing& thing);
Thing x;
std::unique_ptr<Thing> thing_ptr = makeAThing();
useMyThing(x);
useMyThing(*thing_ptr);
更新:
注意问题的更新-存储(非所有权)对此对象的引用。
做到这一点的一种方法确实是存储一个指针。但是,指针存在逻辑错误的可能性,因为它们可以合法地为空。指针的另一个问题是,它们不能与std:: algorithms
和容器很好地配合使用-需要自定义比较功能等。
有一种std::-compliant
方法可以做到-std::reference_wrapper<>
所以而不是这样:
std::vector<Thing*> my_thing_ptrs;
做这个:
std::vector<std::reference_wrapper<Thing>> my_thing_refs;
由于std::reference_wrapper<T>
定义了一个运算符T&
,您可以reference_wrapped
在任何需要一个表达式的表达式中使用该对象T
。
例如:
std::unique_ptr<Thing> t1 = make_thing();
std::unique_ptr<Thing> t2 = make_thing();
std::unique_ptr<Thing> t3 = make_thing();
std::vector<std::reference_wrapper<const Thing>> thing_cache;
store_thing(*t1);
store_thing(*t2);
store_thing(*t3);
int total = 0;
for(const auto& t : thing_cache) {
total += value_of_thing(t);
}
在哪里:
void store_thing(const Thing& t) {
thing_cache.push_back(std::cref(t));
}
int value_of_thing(const Thing& t) {
return <some calculation on t>;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句