Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

trouble using qobject_cast (MOC not seeing Q_OBJECT)



  • Hi Everyone,

    I've got a class that I am defining as a subclass of QAbstractProxyModel, which I will be instantiating inside of QML.

    Here's some info I pulled from DataFilter.h:

    class DataFilter: public QAbstractProxyModel {
    
        Q_OBJECT
     Q_PROPERTY(QObject* source READ getSource WRITE setSourceModel NOTIFY sourceChanged)
    explicit DataFilter(QObject * parent = nullptr);
    

    And here are my setter and constructor definitions for reference:

    DataFilter::DataFilter(QObject *parent):
        QAbstractProxyModel(parent),
        choice(-1),
        source(nullptr),
        mOutputs()
        
    { }
    
    void DataFilter::setSourceModel(QObject *model)
    {
    
        QObject * tester = qobject_cast<DataModel*>(model);
        if (tester) {
            source = qobject_cast<DataModel&>(model);
        }
        else return;
    
    }
    

    This setter is what I am struggling with. BOTH DataFilter and DataModel have been defined with Q_OBJECT (I've been down this road before, so I know the errors), but for some reason, the moc is still not happy. My reason for this approach is to avoid failed casts.

    /home/ghguest/Qt5.9.3/5.9.3/gcc_64/include/QtCore/qglobal.h:738: error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro #define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
    ^
    On this same thought, the source member variable I am setting here is a reference (DataModel& source;). I am unsure if I am choosing the right cast target.

    Overall, I am very confused by this. MOC is not happy, even though I've defined the target of the cast with Q_OBJECT. Here is a code chunk for you non-believers:

    class DataModel: public QAbstractListModel {
    
    Q_OBJECT
        explicit DataModel(const DataModel &model);
    
        explicit DataModel(DataModel &&);
    
        DataModel& operator=(const DataModel &);
    
        DataModel& operator=(DataModel &&);
    

    As you can see, I've also defined my copy & move constructors/assignment operators.

    Any ideas of things to try would be greatly appreciated.

    Thanks in advance!



  • I have solved the issue, and the result makes sense. First I'm going to reveal what I changed to complete an error-free build, then I'm going to explain why this makes sense.

    I fixed my error by changing source; instead of storing a reference, I am now storing a pointer.
    Meaning I went from this:

    DataModel &source;
    

    to this:

    DataModel *source;
    

    When a person stores a reference, they are storing the literal address in memory of that object. Now, because the address of the object in memory is probably tied to a bunch of other locations in memory, it is a time-costly and undesirable operation to copy by reference, because that would include making all the necessary ties to that new memory location.

    Storing a pointer completely avoids the heavy operation of copying all of the arguments data. So instead of copying the object's address and mimicking all of its ties, you just pass a pointer that points to that object's address in memory.

    I hope I was clear and also correct. C++ is a relatively new language to me, but I have done my fair share of reading about move and copy semantics.

    If I have made an error in what I've said here, PLEASE tell me! Eager learner here.


  • Lifetime Qt Champion

    Hi,

    There's one main major point you missed: you can not copy QObject based classes.

    See the QObject documentation on the why.



  • @SGaist Makes total sense.

    Thanks man.


Log in to reply