智能指针而不是指针

smart pointers instead of pointers

对不起我的英语。我有相同的代码:

auto windowsStack = m_windowManger->windowsStack();

auto ListModel = new QStandardItemModel();

while(!windowsStack.empty())
{
    auto window = windowsStack.top();
    auto title = QString::fromUtf8(window->title().c_str());

    auto Items = new QStandardItem(title);
    ListModel->appendRow(Items);

    windowsStack.pop();
}

ui->listView->setModel(ListModel);

一切正常,我的任务是替换指向智能指针的指针。我做过不止一次,我的决定:

auto windowsStack = m_windowManger->windowsStack();

auto ListModel = std::shared_ptr<QStandardItemModel>();

while(!windowsStack.empty())
{
    auto window = std::shared_ptr<Window>(windowsStack.top());
    auto title = QString::fromUtf8(window->title().c_str());

    auto Items = std::shared_ptr<QStandardItem>(new QStandardItem(title));
    ListModel->appendRow(Items.get());

    windowsStack.pop();
}

ui->listView->setModel(ListModel.get());

但最后,我收到消息:程序意外结束。在提示符下,键入:

ListModel->appendRow(Items.get());

新版本:

auto ListModel = std::make_shared<QStandardItemModel>();
while(!windowsStack.empty())
{
    auto window = windowsStack.top();
    windowsStack.pop();
    auto title = QString::fromUtf8(window->title().c_str());
    ListModel->appendRow(new QStandardItem(title));
}

ui->listView->setModel(ListModel.get());
auto ListModel = std::shared_ptr<QStandardItemModel>();

在这一行创建一个空的共享指针ListModel

尝试替换为:

auto ListModel = std::shared_ptr<QStandardItemModel>(new QStandardItemModel());

正如 Ryan 指出的那样,最好使用 std::make_shared,这有助于减少代码量并避免冗余内存分配:

auto ListModel = std::make_shared<QStandardItemModel>();

注意:

我刚刚描述了一个错误。似乎您的代码中还有其他问题。查看 Ryan 的回答以获取更多详细信息。

这里有几个问题。第一个是在评论和 Edgar Rokyans 的回答中指出的,你创建 ListModel 作为一个 shared_ptr 到 null,首先通过分配一个带有 make_shared[=27= 的项目来修复]

auto ListModel = std::make_shared<QStandardItemModel>();

更严重的错误是您在循环内创建元素,然后将非拥有指针传递给 ListModel,当 Items 的析构函数运行时,这些指针在循环结束时变得无效. QStandardItemModeldefined to delete the items it has 所以你不应该使用 shared_ptr 在传递它们之前分配项目。而是分配并调用 appendRow。此外,您将从 windowsStack 获得的内容包装在 shared_ptr 中,但 windowsStack 似乎是一堆拥有指针的副本,所以这是一件奇怪的事情。我不能确定,但​​看起来你真的想在这里使用原始指针,或者使 windowsStack 成为 shared_ptr 的堆栈。我真的不能确定,因为我不知道 windowsStack() 返回了什么——它可能是一堆拥有原始指针的堆栈,这些指针指向调用者应该删除的动态分配的内存。

while(!windowsStack.empty()) {
    auto window = windowsStack.top();
    windowsStack.pop();
    auto title = QString::fromUtf8(window->title().c_str());
    ListModel->appendRow(new QStandardItem(title));
}