查询如何清除派生类对象的内存

时间:2016-03-15 06:58:10

标签: c++ qt

我遇到的情况是我在清除析构函数中的记忆时遇到了崩溃。请参阅以下代码

C ++代码:

class Key{
    ....
};

Class Object {
    ...
};

Class E {

    private:
        vector<Object> m_vector;
};

Class A {
    public:
        virtual void check()=0;
    protected:
        hashmap<Key*,E*> myMap; 
};

A:~A() {
    EMapItr eMapItr = myMap.beginRandom();
    for(; eMaptr; ++eMapItr) {
        delete eMapItr.value();
}
E:~E() {
    m_vector.clear();
}


class B: public A {
    public:
        virtual void check()
    private:
        DB* db;
} 

void B::check() {
    db->create(&myMap);
}

QT Code:

class MyQtAction {
public:
    void act() ;
private:
    GUIObject* guiWindowObject
};
MyQtAction::act() {
    A* aobj = new B();
    if(!guiWindowObject) {
        guiWindowObject = new GUIObject(aobj);
    }
};

class GUIObject:public QWidget {
private:
    A* guiAobj; 
 };

 GUIObject:GUIObject(A* obj) { 
    guiAobj= obj;
 }
 GUIObject:~GUIObject {
 }

现在可以请你在哪里删除A类的点,因为A的对象被多次创建

2 个答案:

答案 0 :(得分:1)

由于您正在使用Qt,我建议您利用其非常强大的“对象树和所有权”模型免费使用它:

  

QObjects在对象树中组织自己。当你创建一个   QObject以另一个对象作为父对象,它被添加到父对象中   children()列表,当父项为。时删除。

http://doc.qt.io/qt-5/objecttrees.html

  • 从QObject派生您的类,并使它们使用/ require QObject作为父参数。

  • 然后,在instanciation,指定父对象(这就是为什么那里 是Qt构造函数中的“父”参数 文档),

  • 不再delete,享受儿童,大孩子的自动删除, 当父母被删除/超出范围时,曾祖母的孩子等。

您可以使用QObject::dumpObjectTree()在运行时可视化父/子树。

http://doc.qt.io/qt-5/qobject.html#dumpObjectTree

现在,可以是一些棘手的情况(参见上面的文档),这可能需要手动显式delete,但根据我的经验,95%的时间没关系 - 在任何情况下因为你的应用程序变得庞大而复杂,所以比自己处理这个问题要容易得多。如果你使用Qt,你肯定想要使用它。这是该框架的一大特色。

编辑:

现在,关于你的开发环境和“它是C ++还是Qt”?

  • 如果你想学习C ++,那就是艰难而好的方式(只需添加一些 有趣的几个Qt图形小部件),那么你必须了解 析构函数,并能够自己处理。

  • 另一方面,如果你想创建一个严肃的Qt应用程序, 然后你必须整个拥抱Qt框架,这个 父/子QObject基本基类,其他所有Qt的 派生类是基本的,非常有用。有一对 其他根本基本Qt概念,如No Copy Constructor or Assignment Operator,与 你到处使用指针的重要结果, 及其理由 here,或Qt's “没有例外”的座右铭,解释说 here,来自 “历史和实际原因”引用文档,如果 在Qt&gt; = 5之前我没有被支持。 在做的时候 Qt,做全Qt。可以想象的核心C ++被埋藏在 表面上。

答案 1 :(得分:0)

你应该在act()中删除它。否则你可能会失去它的痕迹。初始化内存然后将指针传递给对象不是一个好主意(除非情况需要它)。我的建议是在GUIObject的构造函数中移动新的A。当删除GUIObject时,你可以安全地消除A而不会遇到双内存空闲。

这样的事情:

class GUIObject {
    A* aobj;
public:
    GUIObject();
    ~GUIObject();
};

GUIObject::GUIObject()
{
    A* aobj = new B();
}

GUIObject::~GUIObject()
{
    delete aobj;
}