c++ - 唯一指针初始化
问题描述
我还是 C++ 的新手,如果这很明显,我很抱歉,但经过多次谷歌搜索后我找不到一个好的答案。
我希望我可以编写以下代码。
class Test {
public:
Test();
private:
std::unique_ptr<Dummy> m_Dummy;
};
Test::Test() {
auto data = // generate some data here
m_Dummy = std::make_unique<Dummy>(data);
}
会发生什么:
m_Dummy 上的赋值运算符调用unique_ptr::reset
,
它调用指针上的 delete ,
它调用 m_Dummy 析构函数,
并且运行析构函数会创建一个段错误,因为它从未被初始化。
正确的方法是在构造函数初始化列表中对其进行初始化。
但是那样我将无法传递我想要的数据。
Test::Test() : m_Dummy{std::make_unique<Dummy>(data)} { // Don't have time to generate data
}
我不知道如何使这个更清洁。
我目前的想法是将 Dummy 更改为具有默认构造initialize
函数,然后是一个获取数据的函数。
不过感觉不对。
有没有更清洁的方法来处理这个?
需要参数并且还需要成为类成员的智能指针通常会做什么?
谢谢,
内森
编辑:
从下面的答案中,我的代码中的某处可能存在完全不同的问题导致此问题。
这是在抛出段错误之前来自调试器的调用堆栈。
Dummy::~Dummy Dummy.cpp:24
std::default_delete<Dummy>::operator() unique_ptr.h:78
std::unique_ptr<Dummy, std::default_delete<Dummy> >::reset unique_ptr.h:371
std::unique_ptr<Dummy, std::default_delete<Dummy> >::operator= unique_ptr.h:278
Test::Test Test.cpp:42
std::make_unique<Test, int&, double, double> unique_ptr.h:821
World::World World.cpp:25
Application::Run Application.cpp:77
main main.cpp:10
__libc_start_main 0x00007fbd47bbdb97
_start 0x0000555e1df657ea
Edit2:
问题是在创建我的数据的过程中,我破坏了我的记忆,而 Dummy 恰好是受害者。我最初创建 unique_ptr 的建议现在有效。
谢谢
解决方案
会发生什么:调用上
的赋值运算符,m_Dummy
调用 指针,调用析构函数,并运行析构函数会创建一个段错误,因为它从未被初始化。unique_ptr::reset
delete
m_Dummy
这不是在正常情况下发生的事情。
m_Dummy
没有在构造函数中显式Test
初始化,因此它被隐式默认构造,并且其默认构造函数将其持有的指针设置为nullptr
.
当 aunique_ptr
持有nullptr
时,reset()
是一个空操作。分配给unique_ptr
正在持有的 a 是完全安全的nullptr
。
即使reset()
不是无操作,调用delete
.nullptr
也就是说,在分配给时唯一Dummy
可以调用的析构函数是在不持有 a时。为了在您显示的构造函数中发生这种情况,必须处于无效状态,因为:m_Dummy
m_Dummy
nullptr
Test
m_Dummy
在无效内存上调用了
Test
构造函数(不太可能,除非您滥用placement-new
)您要初始化的代码
data
,甚至是Dummy
构造函数本身,正在破坏随机内存,并且m_Dummy
是这种破坏的不知情的受害者(更有可能)。
推荐阅读
- python - 烧瓶 sqlalchemy 将 .h5 文件保存/加载到数据库
- selenium - 詹金斯没有按预定时间运行
- python - 在 Pandas 的低频 bin 中对高频数据进行计算
- alsa - ALSA:snd_pcm_writei 如何影响音频输入
- javascript - Javascript - 如何仅将已从电子表格 B 修改的数据行附加到电子表格 A
- jquery - 循环表单并使用 jQuery 使用 AJAX 提交
- visual-studio-code - 从 winSCP 打开文件时,VScode 在标签栏中显示(已删除)
- for-loop - 即使“for”循环中的命令在詹金斯管道中失败,是否有任何方法可以继续循环
- c++ - 如何在不执行多个 couts 的情况下轻松打印行?(C++)
- javascript - 如何根据常见的子字符串模式减少和变异/更改数组的字符串条目?