Mic*_*ael 21 c++ pointers smart-pointers c++11
假设我有一个由a管理的对象std::unique_ptr.我的代码的其他部分需要访问此对象.传递指针的正确解决方案是什么?我应该只是通过普通指针,std::unique_ptr::get还是应该使用并传递一个std::shared_ptr而不是std::unique_ptr根本?
我有一些偏好,std::unique_ptr因为该指针的所有者实际负责清理.如果我使用共享指针,那么由于共享指针,对象将有可能保持活动状态,即使它实际上应该被销毁.
编辑:不幸的是,我忘了提到指针不仅仅是函数调用的参数,而是存储在其他对象中以构建对象的网络结构.我不喜欢共享指针,因为它不再清楚,谁拥有该对象.
Ric*_*ges 18
如果未传输托管对象的所有权(并且因为它是a unique_ptr,无法共享所有权)那么将被调用函数中的逻辑与所有权概念分开更为正确.我们通过参考调用来做到这一点.
这是一种令人费解的说法:
鉴于:
std::unique_ptr<Thing> thing_ptr;
Run Code Online (Sandbox Code Playgroud)
改变事情:
// declaration
void doSomethingWith(Thing& thing);
// called like this
doSomethingWith(*thing_ptr);
Run Code Online (Sandbox Code Playgroud)
使用Thing而不修改它.
// declaration
void doSomethingWith(const Thing& thing);
// called like this
doSomethingWith(*thing_ptr);
Run Code Online (Sandbox Code Playgroud)
您唯一想要unique_ptr在功能签名中提及的是您转移所有权:
// declaration
void takeMyThing(std::unique_ptr<Thing> p);
// call site
takeMyThing(std::move(thing_ptr));
Run Code Online (Sandbox Code Playgroud)
你永远不需要这样做:
void useMyThing(const std::unique_ptr<Thing>& p);
Run Code Online (Sandbox Code Playgroud)
这是一个坏主意的原因是,如果将useMyThing的逻辑与所有权的概念混淆,从而缩小了重用的范围.
考虑:
useMyThing(const Thing& thing);
Thing x;
std::unique_ptr<Thing> thing_ptr = makeAThing();
useMyThing(x);
useMyThing(*thing_ptr);
Run Code Online (Sandbox Code Playgroud)
更新:
注意到问题的更新 - 存储(非拥有)对该对象的引用.
一种方法是确实存储指针.但是,指针遭受逻辑错误的可能性,因为它们可以合法地为空.指针的另一个问题是它们std:: algorithms与容器不兼容- 需要自定义比较功能等.
有std::-compliant办法做到这一点 -std::reference_wrapper<>
所以不是这样:
std::vector<Thing*> my_thing_ptrs;
Run Code Online (Sandbox Code Playgroud)
做这个:
std::vector<std::reference_wrapper<Thing>> my_thing_refs;
Run Code Online (Sandbox Code Playgroud)
由于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);
}
Run Code Online (Sandbox Code Playgroud)
哪里:
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>;
}
Run Code Online (Sandbox Code Playgroud)
通常,您只需将引用或普通指针传递给希望观察对象的代码的其他部分.
通过引用传递:
void func(const Foo& foo);
std::unique_ptr<Foo> ptr;
// allocate ptr...
if(ptr)
func(*ptr);
Run Code Online (Sandbox Code Playgroud)
通过原始指针传递:
void func(const Foo* foo);
std::unique_ptr<Foo> ptr;
// allocate ptr...
func(ptr.get());
Run Code Online (Sandbox Code Playgroud)
选择将取决于传递空指针的需要.
您有责任确保观察者unique_ptr在销毁后不使用指针或参考.如果你不能保证那么你必须使用shared_ptr而不是a unique_ptr.观察员可以持有一个weak_ptr表明他们没有所有权的人.
编辑:即使观察者希望坚持指针或参考,但它确实使得确保它在unique_ptr被破坏后不会被使用更加困难.
| 归档时间: |
|
| 查看次数: |
3049 次 |
| 最近记录: |