[SOLVED] Calling QObject::parent() fucks things up
-
Sorry for the rudeness but I can only describe the mess I'm in with this. Maybe it's something idiot I'm struggling with but I don't get it.
Sorry for the pseudo-c++ but the real classes are quite big.
I have :
@
class A : public QWidget
{
public:
A(): x(0)
{
m_B = new B(this);
}
~A();
int someAMethod();private:
B* m_B;
int m_x;
}class B : public QWidget
{
public:
B(QWidget* parent): QWidget(parent)
{ }~B();
someBMethod()
{
int z = ((A*) parent())->someAMethod(); // end of the world starts here
}
}
@Now, if my main instanciated A and if I called someBMethod() later in the program I would assume z to be A's m_x, i.e. 0.
But that's not the case, and my program just becomes crazy : I start having random non-related segfaults (sometimes only at the call of someAMethod()), things don't display correctly, and other little pleasures of life.
The thing that shocked me is that when I tried debugging this with gdb, things change when I call parent().To the point to when I was after the line
@int z = ((A*) parent())->someAMethod();@
in the code, the this pointer of the class wasn't even pointing to this class anymore, but to its parent.
It's driving me insane, I even tried it on different computer and OSes to check for bad ram but it is the same comportment on :- linux 64bit w/ gcc 4.7
- os x mountain lion w/ clang
- windows with MinGW.
I'm under qt5.0.1 but I had already this problem in 4.8.
The worst is that if I write B like this :
@
class B : public QWidget
{
public:
B(QWidget* parent): QWidget(parent)
{
m_parent = parent;
}~B();
someBMethod()
{
int z = ((A*) m_parent)->someAMethod(); // end of the world starts here
}private:
QWidget* m_parent;
}
@everything works perfectly.
Help me please.
-
In 'someBMethod()' you will call 'someAMethod()' pass a pointer for A in the B constructor and avoid use the cast.
Like this:
[code]
class A ...class B : public QWidget { public: B(QWidget* parent): QWidget(parent) { m_parent = parent; } ~B(); someBMethod() { int z = aParent->someAMethod(); // end of the world starts here } private: A* m_parent; }
[/code]
But the best solution is use Signal/Slot mechanism
[]'s
-
Yes but why doesn't QObject::parent() work ?
-
[quote author="doom_Oo7" date="1364424445"]
@
int z = ((A*) parent())->someAMethod(); // end of the world starts here
@...
Yes but why doesn’t QObject::parent() work ?
[/quote]QObject::parent() is fine; it's the casting that's the issue.
C-style casts are unsafe, and have led to strange bugs in the past. In general C++, use static_cast() or dynamic_cast() instead. (Sometimes you might need reinterpret_cast(), but it's very unlikely)
If you really want to type-cast QWidgets (or any other QObject), use a "qobject_cast()":http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#qobject_cast
-
Also, parent() returns a parent QObject, and since your class is not a QObject (just because you inherit QWidget doesn't make it QObject, you need Q_OBJECT macro), it might lead to strange bahaviour.
After you add Q_OBJECT you should (like JKSH said) use qobject_cast, which will return 0 and not blow up if the cast fails like the C-style cast you are using.There is also a QWidget::parentWidget() so you can use it for widgets instead of QObject::parent().
-
Okay, thanks.
I had not written it in the pseudo code but my real classes were in fact Q_OBJECT, so using qobject_cast works. Thanks!