【问题标题】:Qt & shared_pointer : execution errorQt & shared_pointer:执行错误
【发布时间】:2012-08-15 04:33:57
【问题描述】:

我正在尝试使用 tr1shared_ptrQt 4.8.2,但我遇到了一些麻烦。 这是我的代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <string>
#include <tr1/memory>
using namespace std::tr1;

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTreeView>
#include <QListView>
#include <QWidget>

#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    shared_ptr<QHBoxLayout> mainLayout(new QHBoxLayout);

    shared_ptr<QTreeView> mainFeeds(new QTreeView);

    mainLayout->addWidget(mainFeeds.get());
    shared_ptr<QWidget> mainWidget (new QWidget);
    mainWidget->setLayout(mainLayout.get()); // <--- this line

    shared_ptr<QWidget> rightWidget(new QWidget);
    shared_ptr<QVBoxLayout> rightLayout(new QVBoxLayout);

    shared_ptr<QListView> rightItems(new QListView);
    rightLayout->addWidget(rightItems.get());

    shared_ptr<QListView> rightPreview(new QListView);
    rightLayout->addWidget(rightPreview.get());

    rightWidget->setLayout(rightLayout.get());
    mainLayout->addWidget(rightWidget.get());

    this->setCentralWidget(mainWidget.get());
}

MainWindow::~MainWindow()
{
    delete ui;
}

以及输出(我使用 Qt Creator):

正在启动 /path/myproject-build-desktop-Qt_4_8_2_in_PATH_local_Release/myproject... 程序意外结束。 /path/myproject-build-desktop-Qt_4_8_2_in_PATH_local_Release/myproject 以代码 0 退出

当我注释标记的行时,程序运行但我有一个空窗口。

我有两个问题:

  1. 为什么这行会出错?
  2. 在 Qt 中使用智能指针(实际上是为了构建健壮的 C++ 代码)是正确的方法吗?

为了您的帮助, 提前, 谢谢。

【问题讨论】:

  • 使用调试器跟踪执行到错误发生点。

标签: c++ qt shared-ptr smart-pointers


【解决方案1】:

要回答您的第二个问题,不,您尝试将 shared_ptrs 与 Qt 一起使用的方式不起作用。

您的共享指针在函数结束时超出范围(这会破坏指向的对象,因为它们是管理对象生命周期的唯一且因此是最后一个 shared_ptr ),而 Qt 对象仍在抓住原始指针刚刚删除的对象。因此,仅出于这个原因,当 Qt 尝试使用无效对象时,您的代码将无法正常工作。那是未定义的行为。

此外,Qt 也进行自己的资源管理。您将指向子对象的原始指针传递给其父对象,当父对象超出范围时,父对象将负责删除子对象。所以此时,无论如何都会调用子对象的析构函数。

【讨论】:

    【解决方案2】:

    Qt 以自己的方式管理对象的生命周期。当您将A 设为B 的子级时,当B 被销毁时,A 将变为delete

    所以,在这一行

    mainWidget->setLayout(mainLayout.get());
    

    你使mainLayout成为mainWidget的孩子。

    由于mainWidgetmainLayout 之后声明,它将首先被删除。 mainLayout 也将被删除。但随后shared_ptr 将尝试再次删除mainLayout

    Qt 中,您应该非常小心地使用智能指针。 Qt 内存管理经常获取对象的所有权(但并非总是如此)。此外,您可能更喜欢使用原生 Qt 智能指针

    【讨论】:

    • 那么,如果我想让事情变得更好,我在处理 Qt 元素时必须不要使用智能指针?
    • @GlinesMome,在处理 Qt 小部件堆栈时,您不应该使用所有者智能指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多