c++ - 在析构函数后打开一个新的 QMainWindow 崩溃

标签 c++ qt destructor qmainwindow

第一个 MainWindow 在主窗口中打开,然后当我尝试打开第二个时 窗口程序崩溃并出现 SIGABRT 。 调试器显示以下几行:

double free or corruption (out): 0x00007fffffffe340 ***

RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'
RTTI symbol not found for class 'QObject'

我想了解调用析构函数的正确方法是什么, 如果我不设置 Qt::WA_DeleteOnClose 属性程序工作和 如果我在第二个窗口中做同样的事情,(即我在第二个 QMainwindow 中打开第三个窗口)即使我设置了 Qt::WA_DeleteOnClose 属性,程序也能正常工作。为什么我不能只在第一个 QMainWindow 中这样做?我主要打开一个?

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_DeleteOnClose);
    QTimer *t = new QTimer(this);
    connect(t,SIGNAL(timeout()),this,SLOT(open_new()));
    t->start(1000);
}

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

void MainWindow::open_new(){
    MainWindow2 *win_2 = new MainWindow2(0);
    win_2->show();
    this->close();
}

最佳答案

在 Qt 中,所有 QWidgets 都是这样管理的:

  1. 所有析构函数都是虚拟的。
  2. 如果一个小部件(好吧,事实上,任何 QObject)都有父级,那么父级将自己删除它(使用 operator delete)。也就是说,所有子部件必须由 operator new 创建,或者必须在父部件创建之前销毁(参见@BenjaminT 评论)。
  3. 如果一个小部件没有父级(即 0)并且设置了 WA_DeleteOnClose 属性,那么它会自己发起对操作符 delete 的调用(通过使用成员函数 deleteLater(),请参阅@BenjaminT 评论),同时处理 close 信号(实际的 delete 被调用,好吧,稍后,即不在插槽代码中,请参阅@DmitrySazonov评论)。同样,(a)应用程序不应该自己做这件事,因为它是多余的; (b) 仍应使用 operator new 创建小部件。
  4. 如果一个小部件没有父级,也没有设置 WA_DeleteOnClose 属性,则由调用应用程序决定如何创建和销毁它。例如,如果 QWidget 是一个堆栈变量,那么它会在从相应函数返回时自动销毁(这在 C++ 中是正常的)。

在您的情况下,第一个 MainWindow 可能不是使用 new 运算符 创建的,因此它不能设置 WA_DeleteOnClose 属性。但是下面的代码应该可以正常工作:

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    MainWindow* w = new MainWindow(0);
    // redundant if the attibute is set inside the class constructor
    //w->setAttribute(Qt::WA_DeleteOnClose);
    w->show();
    return app.exec();
}

关于c++ - 在析构函数后打开一个新的 QMainWindow 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47072891/

相关文章:

c++ - Qt5 中 void QSqlQuery::clear() 和 void QSqlQuery::finish() 有什么区别?

multithreading - QGLWidget的paintGL()方法从哪个Qt线程调用?

c++ - 析构函数无法删除已分配的连续内存块

c++ - vector::emplace_back结果两次调用析构函数

c++ - 高效的 const char* 连接和输出到 std::string

c++ - 覆盖 C++ 中的方法

python - IQtNetwork.QHttp请求凭证问题

C++:堆栈分配的对象是否需要虚拟析构函数?

c++ - 如何检查 lldb 是否可以附加到二进制文件?

c++ - 带有 memset_s 分配器的 std::vector