是一个哨兵 QWidget 一个好主意(以防止在创建和填充布局时出现内存泄漏)



这个取自 http://doc.qt.digia.com/qt/qhboxlayout.html#details 的代码片段,除了一些我不知道的魔法之外,充满了潜在的内存泄漏。

编辑:感谢Nikos C.指出异常安全在Qt中很奇怪,如下所示: http://doc.qt.digia.com/qt/exceptionsafety.html 因此,为了保持我问题的主要意图有效,我更新了示例代码:

 QWidget *window = new QWidget;
 QPushButton *button1 = new QPushButton("One");
 QPushButton *button2 = new QPushButton("Two");
 QPushButton *button3 = new QPushButton("Three");
 QPushButton *button4 = new QPushButton("Four");
 QPushButton *button5 = new QPushButton("Five");
 QMyWidgetThatCanThrow *myWidget = new QMyWidgetThatCanThrow("");
 QHBoxLayout *layout = new QHBoxLayout;
 layout->addWidget(button1);
 layout->addWidget(button2);
 layout->addWidget(button3);
 layout->addWidget(button4);
 layout->addWidget(button5);
 layout->addWidget(myWidget);
 window->setLayout(layout);
 window->show();
只有在最后,

小部件才会被修复到窗口,因此最后两行之前的任何异常都会泄漏所有内容(假设在实际代码中窗口有一个父级)。

在类似的非Qt代码中,我会使用哨兵对象来处理这种事情。是否有一种使用哨兵的最佳实践方法,其他人在查看我的代码时会理解?

编辑:这是可接受的设计模式吗?

void PopulateWindow(QWidget *window)
{
     QWidget sentry;    //serves as the intial parent ensuring that all
                        //widgets are either reparented or deleted
     QPushButton *button1 = new QPushButton("One",&sentry);
     QPushButton *button2 = new QPushButton("Two",&sentry);
     QPushButton *button3 = new QPushButton("Three",&sentry);
     QPushButton *button4 = new QPushButton("Four",&sentry);
     QPushButton *button5 = new QPushButton("Five",&sentry);
     QHBoxLayout *layout = new QHBoxLayout(&sentry);
     layout->addWidget(button1);
     layout->addWidget(button2);
     layout->addWidget(button3);
     layout->addWidget(button4);
     layout->addWidget(button5);
     window->setLayout(layout);
}    //sentry goes out of scope and deletes anything that was not reparented

使用它:

 QWidget *window = new QWidget;
 PopulateWindow(window);
 window->show();

可能出现什么问题? 您要避免的问题是什么?如果您创建小部件并且有任何迫使您中止的内容,请像在常规 C/C++ 中一样执行

if(huhOh!!){
   delete button1;
   delete button2;
   ....
   return false
}

编辑:

没有什么能阻止你做

void PopulateWindow(QWidget *window){
 QPushButton *button1 = new QPushButton("One",window);
 QPushButton *button2 = new QPushButton("Two",window);
 QPushButton *button3 = new QPushButton("Three",window);
 QPushButton *button4 = new QPushButton("Four",window);
 QPushButton *button5 = new QPushButton("Five",window);
 QHBoxLayout *layout = new QHBoxLayout(window);
 layout->addWidget(button1);
 layout->addWidget(button2);
 layout->addWidget(button3);
 layout->addWidget(button4);
 layout->addWidget(button5);
 //layout already set
 //window->setLayout(layout);
}  

在这种情况下,您只需删除window

最新更新