我在看Qt示例here:
在构造函数内部,它们有:
Window::Window()
{
editor = new QTextEdit(); // Memory leak?
QPushButton *sendButton = new QPushButton(tr("&Send message")); // Memory leak?
connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage()));
QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak?
buttonLayout->addStretch();
buttonLayout->addWidget(sendButton);
buttonLayout->addStretch();
QVBoxLayout *layout = new QVBoxLayout(this); // Memory leak?
layout->addWidget(editor);
layout->addLayout(buttonLayout);
setWindowTitle(tr("Custom Type Sending"));
}
带评论的那些行
// Memory leak?
不是那些内存泄漏吗?
如果是这样,既然Window类没有构造函数,那么我应该把所有这些变量(编辑器已经是)Window成员变量?
或者......当Qt超出范围时,Qt会在内部“删除”这些成员变量吗?
答案 0 :(得分:27)
不,addWidget()
功能将保留小部件的所有权。然后它会破坏它拥有的小部件。
此外,您可以阅读here:
与QObjects一样,可以使用父对象创建QWidgets 表示所有权,确保在没有对象时将其删除 使用时间更长使用小部件,这些父子关系有一个 附加含义:每个子窗口小部件都显示在屏幕中 其父窗口小部件占用的区域。这意味着当你删除一个 窗口小部件,它包含的所有子小部件也将被删除。
答案 1 :(得分:7)
如果new和addWidget之间抛出异常,则表示存在内存泄漏。否则,父控件将获得内存的所有权。
QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak?
//make sure you don't throw here
buttonLayout->addWidget(sendButton);
答案 2 :(得分:5)
除了Klaim的正确答案:
我会将这些指针存储在std::auto_ptr
中,同时将它们传递给父级。
std::auto_ptr<QHBoxLayout> buttonLayout( new QHBoxLayout() );
// make things which could throw...
layout->addLayout(buttonLayout.release());
这样你肯定不会有泄漏。
答案 3 :(得分:1)
从C ++ 14开始,您可以使用std::make_unique()
便捷功能模板来创建具有小部件专有所有权的std::unique_ptr<>
。然后,在将小部件传递到addLayout()
的那一刻,您通过调用release()
来使智能指针放弃所有权:
auto buttonLayout = std::make_unique<QHBoxLayout>();
// ...
// an exception could be thrown here
// ...
layout->addLayout(buttonLayout.release());
答案 4 :(得分:0)
由于.release()调用,它不会被双重删除。
注意std :: unique_ptr正在替换std :: auto_ptr。希望QT支持移动语义,然后release()将是layout-&gt; addLayout(std :: move(buttonLayout)),如果没有调用移动,则会出现编译错误。