QObject双重删除

Posted

技术标签:

【中文标题】QObject双重删除【英文标题】:QObject double deletion 【发布时间】:2011-09-08 17:50:48 【问题描述】:

我目前在 Mac OS X 10.6 上运行 Qt 4.7.4。我使用 MacPorts 安装了 Qt。

我一直在尝试使用测试驱动开发作为我编码实践的一部分,为此我正在使用 QtTest。我有一个从 QObject 派生的类,当我尝试测试代码时,我的测试在它应该通过时失败了。我查看了 (test -vs) 的输出,发现以下错误:

INFO : 周期表::ElementTest::testName() 信号:QObject(7fff5fbfd860) 已销毁 ((QObject*)7fff5fbfd860)

在一个测试用例中,我两次观察到上述错误,将实际测试夹在中间。这表明子对象在使用前已被销毁,并且在测试后似乎再次被删除。我已经使用 QPointer 并确认该对象在使用前变得无效。另一种方法是在每个测试用例中初始化变量,从而违背了单次初始化的目的,进而增加了代码膨胀。

class Element : public QObject

   Q_OBJECT
   Q_PROPERTY(QString name READ name WRITE setName NOTIFY valueChanged)
public:
   Element(QObject* parent = 0) : QObject(parent) 
   void setName(const QString& name);
   QString name() const;
Q_SIGNALS:
   void valueChanged(QString value);
private:
   QString elementName;
   Q_DISABLE_COPY(Element);
;

我使用以下命令(通过 cmake):

g++ -D_FORTIFY_SOURCE=2 -D_GLIBCXX_FULLY_DYNAMIC_STRING -D_FORTIFY_SOURCE=2 -DQT_TEST_LIB -DQT_CORE_LIB -DQT_DEBUG -Wformat-security -Wmissing-format-attribute -Wformat=2 -Wctor-dtor-privacy -Wabi -Woverloaded-virtual -Wsign-promo -Wformat-nonliteral -Wdisabled-optimization -Wformat-y2k -Winit-self -Winvalid-pch -Wunsafe-loop-optimizations -Wmissing-format-attribute -Wmissing-include-dirs -Wstrict-aliasing=3 -Wswitch-enum -Wvariadic -macros -Wvolatile-register-var -std=gnu++0x -fmessage-length=0 -ftree-vectorize --param max-unroll-times=4 -pipe -fabi-version=4 -g -I/opt/本地/包含/QtCore -fPIC -fstack-protector -fPIC -fstack-protector -Wstack-protector

我不记得在 Qt 4.6 中遇到过这个问题,而且我对过早销毁感到困惑。

我想这不是 Qt 中的错误,但我很好奇是否有其他人遇到过这样的问题并找到了解决方案。我喜欢 Qt,但这个问题不仅限于单元测试。任何帮助都将不胜感激。

-- 编辑--

测试用例源代码:

在.h文件中

#ifndef  TEST_ELEMENT_H
#define  TEST_ELEMENT_H

#include    <QtCore/QObject>
#include    <QtCore/QPointer>

namespace hashtable


class Element;                                  // Forward declaration

class ElementTest : public QObject

    Q_OBJECT
private Q_SLOTS:
    void initTestCase();

    void testName();

private:
    QString name;
    QPointer<Element> element;
;


#endif

在 .cpp 文件中

void ElementTest::initTestCase()

    name = QString("Hydrogen");
    mass = 1.008;
    QPointer<Element> element(new Element(this));
    return;


void ElementTest::testName()


    element->setProperty("name", name);
    QCOMPARE(element->property("name").toString(), name);

【问题讨论】:

你能给我们看看这个类的测试代码吗? 【参考方案1】:

ElementTest::initTestCase()中的这一行:

QPointer<Element> element(new Element(this));

正在创建一个名为 element 的局部变量,它与成员 ElementTest::element 无关。当ElementTest::initTestCase() 返回时,本地变量将被销毁。

尝试将行更改为:

element = new Element(this);    

【讨论】:

感谢您的快速回复。我应该意识到这会创造一个临时价值。这是被忽视的小错误。

以上是关于QObject双重删除的主要内容,如果未能解决你的问题,请参考以下文章

Casperjs 测试 - 删除 QObject

Qt 如何删除对象?存储 QObject 的最佳方式是啥? [复制]

QObject 使用 setParent() 将 QList 设置为父级

是否可以断开 QObject 的所有连接而不删除它

QJSEngine 删除我的 QObject,如何在 QJSEngine::newQObject 之后更改所有权?

QThread finished() 连接到 QObject 的删除器