2017-08-12 83 views
1

我是相当新的C++,所以我可能不会使用正确的术语。这是我期待的。C++ 11 - 传递引用作为所有权的构造函数参数

我有类FooBar。 我想创建一个Foo的实例。 然后我想创建一个Bar的实例,并将Foo实例传递给构造函数Bar,这样Bar现在拥有Foo的生存期。这样,当Bar's析构函数被调用时,它将/应该取消分配Foo实例。

此外,我想使用户对FooBar的用户明确(使用正确的C++语义),即Bar拥有Foo实例。

我接受任何建议/最佳实践建议以及。

这是我的尝试。 Bar的析构函数中的delete &m_foo;对我来说感觉不对。我也不明白什么:m_foo(foo)真的在Bar的ctor中做什么(它究竟叫什么 - 我会怎么说?)。我会认为在构造函数中做一个赋值是正确的。

class Foo 
{ 
public: 
    Foo(); 
    ~Foo(); 
private: 

}; 

Foo::Foo() 
{ 
} 

Foo::~Foo() 
{ 
} 

class Bar 
{ 
public: 
    Bar(Foo & foo); 
    ~Bar(); 
private: 
    Foo & m_foo; 

}; 

Bar::Bar(Foo & foo) 
    :m_foo(foo) 
{ 
} 

Bar::~Bar() 
{ 
    delete &m_foo; 
} 

这里是我想用它

int main() 
{ 
    auto foo = new Foo(); 
    auto bar = new Bar(*foo); 
    delete bar; 
    return 0; 
} 

回答

2

正确的方式做,这是std::unique_ptr

#include <memory> 


class Foo 
{ 
public: 
    Foo() {} 
    ~Foo() {} 
private: 

}; 

class Bar 
{ 
public: 
    Bar(std::unique_ptr<Foo> foo); 
    ~Bar() 
    { 
     // m_foo will be destroyed at the end, and the Foo object 
     // that m_foo points to will be destroyed as well. 
    } 
private: 
    std::unique_ptr<Foo> m_foo; 

}; 

Bar::Bar(std::unique_ptr<Foo> foo) 
    // This section after the colon and before the open brace 
    // is the member initializer list. This defines what 
    // arguments are passed to the constructors of the members. 
    : m_foo(std::move(foo)) 
     // std::move is required here to make it clear that 
     // you are transferring ownership to the member. It 
     // causes the move constructor to be used instead of 
     // the copy constructor. 
{ 
} 

int main() 
{ 
    Bar bar(std::unique_ptr<Foo>(new Foo)); 
    return 0; 
} 

你必须访问的成员作为一个指针而不是一个参考。

使用C++ 14时,您希望使用std::make_unique构造您的Foo指针,但由于这是一个C++ 11问题,​​因此我使用了new

+0

是的,我会喜欢使用'std :: unique_ptr'功能,但我相信这是一个C++ 14功能,不是吗?我无法在我正在使用的环境/工具链中使用此功能(嵌入式)。 –

+1

std :: unique_ptr是一个C++ 11功能,而std :: make_unique是一个C++ 14功能。编辑:我看到你正在使用C++ 11,尽管不太安全,但你可以简单地使用std :: unique_ptr构造函数就地执行std :: make_unique。 – Harrand

+0

@ShivKumar:与C++ 11唯一的区别是你没有'std :: make_unique'。你可以编写自己的或使用新的代替。我更新了我的答案,不使用'std :: make_unique'。 –

相关问题