【问题标题】:Dynamically allocated objects in main() Qt projectmain() Qt 项目中动态分配的对象
【发布时间】:2013-10-28 16:25:10
【问题描述】:

我的int main() 中有几个动态分配的对象,我应该如何在程序结束时删除它们?目前我认为我没有在程序结束时释放内存,这是主要的:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *w = new MainWindow;
    breadData *dat = new breadData("audit.dat");
    //link main window with bread data
    w->_link(dat);
    //show main window
    w->show();
    //execute loop
    return a.exec();
}

【问题讨论】:

  • 实际上,您不必这样做。通常在 QT 程序中它们不会。但这给了我意志力,所以我尽量避免这种模式(要么创建对象的具体实例,要么使用智能指针)。
  • @MadScienceDreams 您不必在其他对象拥有的对象之后释放内存(父子关系)。在 OP 的代码中没有这种关系。

标签: c++ qt object dynamic


【解决方案1】:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *w = new MainWindow;
    breadData *dat = new breadData("audit.dat");
    //link main window with bread data
    w->_link(dat);
    //show main window
    w->show();
    //execute loop
    int result = a.exec();
    delete dat;
    delete w;
    return result;
}

但动态分配看起来没有必要。
为什么不

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    breadData dat("audit.dat");
    //link main window with bread data
    w._link(&dat);
    //show main window
    w.show();
    //execute loop
    return a.exec();
}

【讨论】:

  • 动态分配现在看起来确实很随意。感谢第二次 sn-p
【解决方案2】:

你是对的,现在你正在泄漏MainWindow 的一个实例和breadData 的一个实例。

对于QObject 实例,最简单的做法是使用内置内存管理。让您的 QObjects 归 QApplication 所有,它们将在 QApplication 被销毁时被删除。

对于其他对象,使用智能指针 - 无论如何都应该这样做!

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget g; // dummy, just to demonstrate ownership - will delete children
               // upon leaving the scope
    // 1. For QObjects/QWidgets
    // 1a. use QObject/QWidget ownership
    MainWindow *w = new MainWindow(&g);
    // 1b. or use a smart pointer
    QScopedPointer<MainWindow> w(new MainWindow);
    // 2. For any other class: use smart pointers
    QScopedPointer<breadData> dat(new breadData("audit.dat"));
    //link main window with bread data
    w->_link(dat);
    //show main window
    w->show();
    //execute loop
    return a.exec();
}

顺便说一句,当读取文件或解析文件失败时,breadData 构造函数最好抛出异常。否则你会得到一个“无效”的对象,祝你好运,确保应用程序的其余部分知道如何处理它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    相关资源
    最近更新 更多