在课堂成员的背景下阅读了很多关于(智能)指针的内容后,我仍然不确定如何处理以下情况。
我想通过调用实例化特定Bar对象的deafult构造函数,或者通过将某种指针传递给Foo的一个参数构造函数来创建Foo类型的对象。
所以在下面的代码片段中(当然没有编译),m_bar应该是什么类型的?
struct Bar {
Bar(int k) {}
Bar operator=(const Bar&) =delete;
Bar (const Bar&) = delete;
};
struct Foo {
Foo() : m_bar(5) {}
Foo(Bar b) : m_bar(b);
Bar m_bar;
};
答案 0 :(得分:1)
- 我不能使用unique_ptr,因为我仍然需要访问Foo之外的Bar对象。
unique_ptr不会阻止您访问Foo之外的对象。
如果你的意思是"我仍然需要访问Foo对象生命周期之外的Bar对象",那么你的推理是合理的。在这种情况下,Foo不能成为对象的唯一所有者。
- 如果我使用了原始指针,那么如果调用了Foo的deafult构造函数,我需要调用delete但是如果调用了one-arg ctr则不需要调用delete。
指针必须且只能由其所有者删除。通过声明Foo必须删除指针,你暗示Foo拥有指针。
如果对象也可以由其他东西拥有,那么设计似乎会导致共享所有权。
- 然后有shared_ptr,但引用Herb Sutter&#34;不要将智能指针作为函数参数传递,除非你想使用或操纵智能指针本身,例如< strong>分享或转移所有权。&#34;
根据说明,似乎共享所有权正是您正在尝试做的事情,并且Herb明确列出了其中传递智能指针的情况之一。
现在,由于所有权有条件地在这里&#34;在这里&#34;或&#34;那里&#34;,共享指针并非完全必要。它只是最简单的解决方案,因此是一个很好的解决方案。
您可以根据自己的情况设想maybe_unique_ptr
。标准库中不存在这样的智能指针。以下别名模板可能对您有用,但取决于boost:
template<class T>
using maybe_unique_ptr = boost::variant<std::unique_ptr<T>, T*>;
struct Foo {
Foo() : bar(std::make_unique<Bar>(5)) {}
Foo(Bar* b) : bar(b) {}
maybe_unique_ptr<Bar> bar;
};
这当然意味着您必须使用boost::apply_visitor
访问变体中的实例,这会使其更加麻烦。