Adding a virtual function causes strange result...
-
I have added a virtual function to a base class:
virtual QString strGetData();
In the prototype of the base class:
QString clsXMLinterface::strGetData() { return ""; }
I have a number of classes derived from this class, one of my classes, prototype:
class clsQtLineEdit : public QLineEdit, public clsXMLinterface { Q_OBJECT
Under the public modifier:
QString strGetData();
The implementation:
QString clsQtLineEdit::strGetData() { return text(); }
With this code as soon as I build and execute within Qt Creator the execution stops in qlist.h on line 115:
inline int size() const noexcept { return int(d->end - d->begin); } // q6sizetype
I am using, Qt Creator 4.15.0-beta2 (4.14.83), Based on Qt 5.15.2 (Clang 11.0 (Apple), 64 bit), Built on Mar 24 2021 04:43:31
The executable is using Qt 5.15.2, this behaviour doesn't happed if I remove the virtual keyword.
Can anyone help with why this is happening?
-
@SPlatten Stops with what error/exception?
Try to add override key-word to strGetData() in your subclass.
And please provide more context:- Which exact strGetData() is called when application stops?
- What are you doing with the returned value?
-
@jsulm , this is where its called:
QString clsScriptHelper::getValue(const QString& crstrID) { QString strValue; if ( crstrID.isEmpty() != true ) { clsXMLnode* pobjNode(clsXMLnode::spobjGetNodeById(crstrID)); if ( pobjNode != nullptr ) { clsXMLinterface* pobjXMLif(reinterpret_cast<clsXMLinterface*>(pobjNode)); if ( pobjXMLif != nullptr ) { strValue = pobjXMLif->strGetData(); } } } return strValue; }
The prototype for the above:
Q_INVOKABLE QString getValue(const QString& crstrID);
There is presently only one call to this, the only overridden instance is defined in the class clsQtLineEdit.
Execution stops as I stated on the line I specified in the original post, how can I see if an error or exception has occurred because it isn't obvious.
-
@SPlatten said in Adding a virtual function causes strange result...:
how can I see if an error or exception has occurred because it isn't obvious
You should see it in debugger.
Please post the stack trace. -
@jsulm :
1 QListData::size() const qlist.h 115 0x10000799f 2 QList<std::pair<QString, QString>>::length() const qlist.h 360 0x100043265 3 clsXMLnode::strGetAttribute(QString) clsMainWnd.cpp 4281 0x100028276 4 clsQtLayout::addButton(QAbstractButton *, QString const&) clsQtLayout.cpp 149 0x10008ad47 5 clsXMLnode::setWidget(QWidget *) clsMainWnd.cpp 3860 0x10002b026 6 clsQtRadioButton::clsQtRadioButton(clsXMLnode *, QString *, QWidget *) clsQtRadionButton.cpp 40 0x1000a6a8f 7 clsQtRadioButton::clsQtRadioButton(clsXMLnode *, QString *, QWidget *) clsQtRadionButton.cpp 38 0x1000a993d 8 clsCNT::pCreate(clsXMLnode *, QString const&, QString&, QStringList&, QWidget *) clsCNT.cpp 141 0x100005f59 9 clsXMLnode::clsXMLnode(QStringList&, clsXMLnode *) clsMainWnd.cpp 766 0x1000232c9 10 clsXMLnode::clsXMLnode(QStringList&, clsXMLnode *) clsMainWnd.cpp 545 0x10002ed35 11 clsScriptHelper::addNodesToGUI(clsXMLnode *, QLayout *, QJsonArray&, int *, int *) clsScriptHelper.cpp 317 0x1000bf08b 12 clsScriptHelper::addNodesToGUI(clsXMLnode *, QLayout *, QJsonArray&, int *, int *) clsScriptHelper.cpp 419 0x1000bfed7 13 clsScriptHelper::addNodesToGUI(clsXMLnode *, QLayout *, QJsonArray&, int *, int *) clsScriptHelper.cpp 419 0x1000bfed7 14 clsScriptHelper::addGUIelement(QJsonObject const&) clsScriptHelper.cpp 232 0x1000bd8c2 15 clsScriptHelper::qt_static_metacall(QObject *, QMetaObject::Call, int, void * *) moc_clsScriptHelper.cpp 216 0x1000dae2a 16 clsScriptHelper::qt_metacall(QMetaObject::Call, int, void * *) moc_clsScriptHelper.cpp 303 0x1000db8dc 17 CallMethod(QQmlObjectOrGadget const&, int, int, int, int *, QV4::ExecutionEngine *, QV4::CallData *, QMetaObject::Call) qv4qobjectwrapper.cpp 1301 0x1012bf559 18 CallPrecise(QQmlObjectOrGadget const&, QQmlPropertyData const&, QV4::ExecutionEngine *, QV4::CallData *, QMetaObject::Call) qv4qobjectwrapper.cpp 1569 0x1012bb753 19 QV4::QObjectMethod::callInternal(QV4::Value const *, QV4::Value const *, int) const qv4qobjectwrapper.cpp 2131 0x1012bafda 20 QV4::FunctionObject::call(QV4::Value const *, QV4::Value const *, int) const qv4functionobject_p.h 202 0x1012e97bc 21 QV4::Runtime::CallProperty::call(QV4::ExecutionEngine *, QV4::Value const&, int, QV4::Value *, int) qv4runtime.cpp 1448 0x1012e9799 22 QV4::Moth::VME::interpret(QV4::CppStackFrame *, QV4::ExecutionEngine *, const char *) qv4vme_moth.cpp 727 0x1012d56b0 23 QV4::Moth::VME::exec(QV4::CppStackFrame *, QV4::ExecutionEngine *) qv4vme_moth.cpp 463 0x1012d4542 24 QV4::ArrowFunction::virtualCall(QV4::FunctionObject const *, QV4::Value const *, QV4::Value const *, int) qv4functionobject.cpp 528 0x10127d8cf 25 QV4::FunctionObject::call(QV4::Value const *, QV4::Value const *, int) const qv4functionobject_p.h 202 0x1012e9578 26 QV4::Runtime::CallName::call(QV4::ExecutionEngine *, int, QV4::Value *, int) qv4runtime.cpp 1406 0x1012e9562 27 QV4::Moth::VME::interpret(QV4::CppStackFrame *, QV4::ExecutionEngine *, const char *) qv4vme_moth.cpp 766 0x1012d5c13 28 QV4::Moth::VME::exec(QV4::CppStackFrame *, QV4::ExecutionEngine *) qv4vme_moth.cpp 463 0x1012d4542 29 QV4::Function::call(QV4::Value const *, QV4::Value const *, int, QV4::ExecutionContext const *) qv4function.cpp 69 0x10127a985 30 QV4::Script::run(QV4::Value const *) qv4script.cpp 162 0x1012af6ca 31 QJSEngine::evaluate(QString const&, QString const&, int) qjsengine.cpp 545 0x101237d86 32 clsJSON::blnDecodeAccordingToType(QJsonObject const&, QTcpSocket *) clsJSON.cpp 377 0x10001859d 33 clsModule::manageReceivedData(QTcpSocket *) clsModule.cpp 230 0x100069269 34 clsServer::onReadyRead() clsListener.cpp 84 0x10001b1e1 35 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (clsServer:: *)()>::call(void (clsServer:: *)(), clsServer *, void * *) qobjectdefs_impl.h 152 0x10001d1ab 36 void QtPrivate::FunctionPointer<void (clsServer:: *)()>::call<QtPrivate::List<>, void>(void (clsServer:: *)(), clsServer *, void * *) qobjectdefs_impl.h 185 0x10001d11d 37 QtPrivate::QSlotObject<void (clsServer:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 418 0x10001d072 38 QObject::event(QEvent *) qobject.cpp 1314 0x10278bb9f 39 QApplicationPrivate::notify_helper(QObject *, QEvent *) qapplication.cpp 3632 0x100b8c9ea 40 QApplication::notify(QObject *, QEvent *) qapplication.cpp 0x100b8de11 41 QCoreApplication::notifyInternal2(QObject *, QEvent *) qcoreapplication.cpp 1063 0x102760a34 42 QCoreApplication::sendEvent(QObject *, QEvent *) qcoreapplication.cpp 1458 0x102761d79 43 QCoreApplicationPrivate::sendPostedEvents(QObject *, int, QThreadData *) qcoreapplication.cpp 1817 0x102761d64 44 QCocoaEventDispatcherPrivate::processPostedEvents() qcocoaeventdispatcher.mm 904 0x102232259 45 QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *) qcocoaeventdispatcher.mm 927 0x1022329c8 46 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0x7ff8188138fd 47 __CFRunLoopDoSource0 (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0x7ff818813865 48 __CFRunLoopDoSources0 (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0x7ff8188135e4 49 __CFRunLoopRun (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0x7ff81881201b 50 CFRunLoopRunSpecific (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0x7ff8188115dd 51 RunCurrentEventLoopInMode (x86_64) /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox 0x7ff8214444f1 52 ReceiveNextEventCommon (x86_64) /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox 0x7ff821444247 53 _BlockUntilNextEventMatchingListInModeWithFilter (x86_64) /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox 0x7ff821443fe5 54 _DPSNextEvent (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit 0x7ff81b240b4c 55 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit 0x7ff81b23f1b8 56 -[NSApplication run] (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit 0x7ff81b2315a9 57 QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) qcocoaeventdispatcher.mm 437 0x10223162f 58 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) qeventloop.cpp 139 0x10275cacf 59 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) qeventloop.cpp 232 0x10275caab 60 QCoreApplication::exec() qcoreapplication.cpp 1371 0x102761042 61 main XMLMPAM.cpp 120 0x1000d3cf4 62 start (x86_64) /usr/lib/dyld 0x1002e94fe
-
this minimal example works like a charm:
class clsXMLinterface { public: virtual QString strGetData(); }; QString clsXMLinterface::strGetData() { return ""; } class clsQtLineEdit : public QLineEdit, public clsXMLinterface{ Q_OBJECT public: clsQtLineEdit(QWidget*parent = nullptr) : QLineEdit(parent) {} public: QString strGetData() override {return text();} }; int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); clsQtLineEdit t; t.show(); return app.exec(); } #include "main.moc"
-
@SPlatten said in Adding a virtual function causes strange result...:
clsXMLnode::strGetAttribute(QString)
You should check what is happening there
-
@SPlatten said in Adding a virtual function causes strange result...:
reinterpret_cast
when using virtual inheritance !?!?!?
use dynamic_cast or if QObject classes object_cast
reinterpret_cast takes the raw pointer and considers it as being of the derived type. However, because of the virtual inheritance, a slight adjustment must be done to the pointer to point to the correct method dispatch table, and that's precisely what dynamic_cast will do.
just as wrong, but probably wouldn't have resulted in a crash would be the use of static_cast.
-
This post is deleted!
-
@SPlatten said in Adding a virtual function causes strange result...:
I didn't use the override keyword, should I?
Yes you should. To ask the compiler to check whether you're really overriding virtual method. Can help to detect bugs at compile time.
As I suggested: check what is happening in clsXMLnode::strGetAttribute(QString).
My guess is that the strGetData() method from base class is called which returns an empty string, so the code then fails later. -
@SPlatten said in Adding a virtual function causes strange result...:
I've replaced reinterpret_cast with dynamic_cast, same result.
For sure not.
btw: dynamic_cast was proposed to your exact same problem some weeks ago already: https://forum.qt.io/topic/132420/how-to-access/4
-
@Christian-Ehrlicher That issue was resolved, this is new and dynamic_cast wasn't used to resolve the last issue, it was resolved with the suggested qobject_cast.
-
@SPlatten said in Adding a virtual function causes strange result...:
it was resolved with the suggested qobject_cast.
Since your class is derived from QObject you can also use qobject_cast. Please learn the basics.