智能指针和不可复制的成员字段
Smart Pointers and non-copyable member fields
在阅读了大量关于类成员上下文中的(智能)指针的内容后,我仍然不确定如何处理后续情况。
我想创建Foo类型的对象,方法是调用实例化特定Bar对象的deafult构造函数,或者将某种指针传递给Foo的单参数构造函数。
- 我不能使用unique_ptr,因为我仍然需要访问Foo之外的Bar对象
- 如果我使用了原始指针,那么如果调用了Foo的deafult构造函数,我将需要调用delete,但如果调用了一个arg-ctr,则不需要调用delete
- 然后是shared_ptr,但引用Herb Sutter的话:"不要将智能指针作为函数参数传递,除非你想使用或操纵智能指针本身,例如共享或转移所有权。"
那么,在下面的片段中(当然不编译),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;
};
- 我不能使用unique_ptr,因为我仍然需要访问Foo之外的Bar对象
unique_ptr不会阻止您访问Foo之外的对象。
如果你的意思是"我仍然需要在Foo对象的生命周期之外访问Bar对象",那么你的推理是合理的。在这种情况下,Foo不能成为对象的唯一所有者。
- 如果我使用了原始指针,那么如果调用了Foo的deafult构造函数,我将需要调用delete,但如果调用了一个arg-ctr,则不需要调用delete
指针必须并且只能由其所有者删除。通过声明Foo必须删除指针,就意味着Foo拥有指针。
如果对象也可以由其他人拥有,那么设计似乎会导致共享所有权。
- 然后是shared_ptr,但引用Herb Sutter的话:"不要将智能指针作为函数参数传递,除非您想使用或操纵智能指针本身,例如共享或转移所有权。"
根据描述,持股似乎正是你想要做的事情,Herb明确将其列为传递智能指针的合适情况之一。
现在,由于所有权是有条件的"在这里"或"在那里",所以共享指针并不是完全必要的。这只是最简单的解决方案,因此也是一个很好的解决方案。
对于您的情况,您可以想象maybe_unique_ptr
。这样的智能指针在标准库中不存在。以下别名模板可能适用于您,但取决于提升:
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
访问变体中的实例,这会使它更加麻烦。
相关文章:
- C++:用户定义的类,以成员字段作为地址
- 用于基于成员字段或函数创建比较器的快捷方式
- uninit_member:非静态类成员字段 m_cJobState.bstatus 未在此构造函数中初始化,也不在其调
- 派生类中的成员字段别名(无访问器功能)
- 如何使用 Clang 查找所有成员字段读/写?
- C 模板功能在任何集合成员字段上迭代
- 一次启用 MANY 类的成员字段,具体取决于模板<T>
- 如何在C++的专用模板类中访问模板类成员字段
- 动态链接到 c++ 静态成员字段时符号查找失败
- std :: async在成员字段的成员功能上
- C++使用成员字段设置比较器
- C++11 是否重新初始化初始化的成员字段
- 将控件作为成员字段传递给使用新 connect() 调用的方法
- 构造以shared_ptr作为成员字段的类的正确语法是什么
- 成员字段的 getter 的常用做法是什么?
- c++:对于多重继承类的子类中的重复成员字段,什么是好的重构
- C++ -- 将元素添加到私有成员字段 std::vector
- 重写派生类中的成员字段
- 在C++类中使用指针作为成员字段是不是很傻
- 模板继承成员字段