智能指针而不是指针

时间:2016-12-14 06:24:48

标签: c++ c++11 pointers smart-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());

2 个答案:

答案 0 :(得分:3)

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的答案了解更多详情。

答案 1 :(得分:3)

这里有几个问题。第一个是在评论和Edgar Rokyans的回答中指出,您将ListModel创建为shared_ptr为null,首先通过使用make_shared

分配项目来修复
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));
}