Qt&shared_pointer:执行错误

Qt & shared_pointer : execution error

本文关键字:执行 错误 pointer shared Qt      更新时间:2023-10-16

我尝试使用 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):

Start/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++代码)的正确方法吗?

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

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

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

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

Qt以自己的方式管理对象的生命周期。当你A B的孩子时,A就会被delete B毁灭。

所以,在这一行

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

你使mainLayout mainWidget的孩子.

正如mainWidget mainLayout后声明的那样,它将首先被删除。mainLayout也将被删除。但是shared_ptr会再次尝试删除mainLayout

Qt你应该非常小心地使用智能指针。Qt模因管理通常拥有对象的所有权(但并非总是如此)。此外,您可能更喜欢使用本机Qt智能指针

  • QPointer作为指向QObject的周指针
  • QScopedPointer作为std::unique_ptr等的替代品。
  • QSharedPointer/QExplicitlySharedPointer用于碎指针。