std::make_unique 中丢失的 C++ 智能指针
C++ Smart Pointer Lost in std::make_unique
我正在转换一些遗留代码以利用 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
不为空。但是,一旦我在 SomeClass
构造函数中,应用程序在尝试初始化 m_Field
时崩溃,因为 ctorArg
为 null(空)。这是预期的吗?如果我将构造函数签名更改为 std::unique_ptr<int> &&
,我会看到同样的问题。有人可以解释一下这段代码的问题是什么,以及如何解决它吗?
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) {
}
};
也就是说,始终按照字段声明的顺序提及初始值设定项,并且不要使用已移出的输入参数。
我正在转换一些遗留代码以利用 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
不为空。但是,一旦我在 SomeClass
构造函数中,应用程序在尝试初始化 m_Field
时崩溃,因为 ctorArg
为 null(空)。这是预期的吗?如果我将构造函数签名更改为 std::unique_ptr<int> &&
,我会看到同样的问题。有人可以解释一下这段代码的问题是什么,以及如何解决它吗?
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) {
}
};
也就是说,始终按照字段声明的顺序提及初始值设定项,并且不要使用已移出的输入参数。