我遇到的情况是我在清除析构函数中的记忆时遇到了崩溃。请参阅以下代码
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的对象被多次创建
答案 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;
}