【问题标题】:C++ 11 - Pass a reference as a constructor argument for ownershipC++ 11 - 将引用作为所有权的构造函数参数传递
【发布时间】:2018-01-20 22:15:43
【问题描述】:

我是相当新的 C++,所以我可能没有使用正确的术语。这就是我想要做的事情。

我有 Foo 和 Bar 的课程。 我想创建一个Foo 的实例。 那么我想创建一个Bar 的实例并将Foo 实例传递给Bar 的构造函数,这样Bar 现在就拥有Foo 的生命周期。这样,当调用 Bar's 析构函数时,它将/应该取消分配 Foo 实例。

另外,我想让Foo 和Bar 的用户清楚地看到(使用正确的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;
}

【问题讨论】:

    标签: c++11 pass-by-reference delete-operator


    【解决方案1】:

    正确的做法是使用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。

    【讨论】:

    • 是的,我很想使用 std::unique_ptr 功能,但我相信这是 C++ 14 的功能,不是吗?我无法在我正在使用(嵌入式)的环境/工具链中使用此功能。
    • std::unique_ptr 是 C++11 功能,而 std::make_unique 是 C++14 功能。编辑:我看到您使用的是 C++11,您可以简单地使用 std::unique_ptr 构造函数代替 std::make_unique 尽管安全性较低。
    • @ShivKumar:与 C++11 的唯一区别是您没有 std::make_unique。您可以自己编写或使用 new 代替。我已经更新了我的答案,不使用std::make_unique。
    • @ShivKumar:我添加了一些 cmets。看看有没有帮助。
    • @ShivKumar:其实是move构造函数,不过也差不多。
    猜你喜欢
    • 1970-01-01
    • 2016-04-21
    • 2015-08-02
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2011-06-28
    • 2011-09-04
    相关资源
    最近更新 更多