【问题标题】:Does resetting a QValidator leak memory?重置 QValidator 是否会泄漏内存?
【发布时间】:2014-12-02 19:07:58
【问题描述】:

我很好奇是否有人知道通过将QValidator 重置为零来删除它是否会泄漏内存。 QT Documentation 提到验证器已“删除”,但这是否也意味着它已被删除?

我的意思的一个例子......

QLineEdit edit;
edit.setValidator(new QIntValidator(0,100));

// .... use the line edit

edit.setValidator(0);

【问题讨论】:

  • 请记住,父级将保留子 QObjects 的列表,并且当父级被销毁时,它将释放其子级。我希望 QIntValidator 是 QLineEdit 的孩子。 qt-project.org/doc/qt-4.8/qobject.html#dtor.QObject
  • @drescherjm 好像不正确,请看我的回答,我加了解释,lineEdit 没有所有权。
  • @Chernobyl 看来你是对的。这是 Qt-4.8.6 的内部结构:void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); } 这是来自文件:qlinecontrol_p.h
  • @drescherjm 看到了这个,只是没加这个回答,我加了代码和输出的例子,我觉得足以证明了。
  • @drescherjm 我认为它不拥有验证器的所有权,因为它允许您通过多个小部件使用单个验证器实例。

标签: c++ qt memory-leaks


【解决方案1】:

不,0 不会删除 validator,只会从 lineEdit 中删除 validator。如果你还想使用

edit.setValidator(new QIntValidator(0,100));

然后你可以删除它:

ui->lineEdit->setValidator(new Validator);
QValidator *vaal = const_cast<QValidator *>(ui->lineEdit->validator());//validator returns const, we use const_cast to avoid problems
vaal->deleteLater();

(const_cast<QValidator *>(ui->lineEdit->validator()))->deleteLater();
//here we just does not create unnecessary QValidator *vaal

其中Validator 是一个子类:

Validator::~Validator()
{
   qDebug() <<"~Validator";
}

输出是:

~Validator 

或者只使用:

Validator *vaal = new Validator;
ui->lineEdit->setValidator(vaal);
ui->lineEdit->setValidator(0);
vaal->deleteLater();

输出相同。

此外,当您使用setValidator 时,QLineEdit 不会获得此validator 的所有权。见下一个代码:

ui->lineEdit->setValidator(new QIntValidator(0,100,this));
qDebug() << ui->lineEdit->validator()->parent();

在我的情况下输出:MainWindow(0x28fdc8, name = "MainWindow") 如您所见,它不是lineEdit

ui->lineEdit->setValidator(new QIntValidator(0,100));
qDebug() << ui->lineEdit->validator()->parent();

输出为:QObject(0x0)

删除validator 是您的责任。

【讨论】:

  • 所以当我做 ui-&gt;lineEdit-&gt;setValidator(new QIntValidator(0,100,this)); 时,this 会删除用新创建的验证器吗?在这种情况下没有内存泄漏?也许,ui-&gt;lineEdit-&gt;setValidator(new QIntValidator(0,100,ui-&gt;lineEdit)); 更好还是没关系?
  • @Oleksandra 您需要阅读 Qt 中的父子关系。如果您使用 Qt Designer,则 lineEdit 的父级是 centralWidget,它的父级是“this”。因此,this 或 lineEdit 无关紧要,干净的代码使用“this”。关于泄漏:这个验证器将用“this”删除(例如 MainWindow 类)。如果你需要提前释放内存,那么你应该自己删除验证器
【解决方案2】:

只需设置验证器的父级,例如。 g.:

QLineEdit edit;
edit.setValidator(new QIntValidator(0,100,&edit));

在这种情况下,QLineEdit 的析构函数将删除验证器。

【讨论】:

    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 2013-04-04
    • 2012-09-13
    • 2020-07-22
    • 2010-10-13
    • 2019-01-28
    • 2015-02-07
    • 2012-02-20
    相关资源
    最近更新 更多