智能指针和不可复制的成员字段

时间:2016-07-28 15:24:03

标签: c++ oop c++11 smart-pointers

在课堂成员的背景下阅读了很多关于(智能)指针的内容后,我仍然不确定如何处理以下情况。

我想通过调用实例化特定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;
};

1 个答案:

答案 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访问变体中的实例,这会使其更加麻烦。