C ++智能指针丢失在std :: make_unique中

时间:2019-03-13 16:29:28

标签: c++ smart-pointers unique-ptr

我正在转换一些旧代码以利用C ++中的智能指针。但是,我遇到了一个运行时问题,正在努力解决。我有如下代码:

struct foo {
    int field;
};

class SomeClass {
private:
    std::unique_ptr<foo> m_Foo;
    int m_Field;
public:
    SomeClass(std::unique_ptr<int> ctorArg)
        : m_Field(ctorArg->field), m_Foo(std::move(ctorArg)) {
    }
};

std::unique_ptr<foo> fooPtr{ new foo() };
auto const classInstance{ std::make_unique<SomeClass>(std::move(fooPtr)) };

如果在调用SomeClass构造函数之前放置了一个断点,则可以验证fooPtr不为null。但是,一旦进入SomeClass构造函数,由于m_Field为空(空),尝试初始化ctorArg时应用程序崩溃。这是预期的吗?如果我将构造函数签名更改为std::unique_ptr<int> &&,则会遇到相同的问题。有人可以解释这段代码的问题是什么,以及如何解决它吗?

1 个答案:

答案 0 :(得分:2)

member-initializer-list的顺序无关紧要,成员将按照其声明的顺序进行初始化。

因此,首先m_Foo(std::move(ctorArg))会将ctorArg归零然后 m_Field(ctorArg->field)将尝试取消引用空的ctorArg

将代码更改为:

class SomeClass {
private:
    std::unique_ptr<foo> m_Foo;
    int m_Field;
public:
    SomeClass(std::unique_ptr<int> ctorArg)
        : m_Foo(std::move(ctorArg)), m_Field(m_Foo->field) {
    }
};

也就是说,始终以声明字段的顺序提及初始化程序,并且不要使用已经移出的输入参数。