Qt, не удается преобразовать аргумент неполного типа ‘A *’ в ‘const QObject *’

#c #qt

#c #qt

Вопрос:

Я новичок в Qt, и когда я изучаю слоты / сигналы, я нахожу странное поведение.

Если я напишу следующий код, все в порядке.

 class A;
class B;

class A : public QObject {
Q_OBJECT

signals:
    void signal(B*);
};

class B : public QObject {
Q_OBJECT

public slots:
    void slot(B*) {};

public:
    void f(A* a) {
        connect(a, SIGNAL(signal(B*)), this, SLOT(slot(B*)));
    }
};
  

Но если я поменяю определение класса A и класса B:

 class A;
class B;

class B : public QObject {
Q_OBJECT

public slots:
    void slot(B*) {};

public:
    void f(A* a) {
        connect(a, SIGNAL(signal(B*)), this, SLOT(slot(B*)));
    }
};

class A : public QObject {
Q_OBJECT

signals:
    void signal(B*);
};
  

Я получаю сообщение об ошибке:

 main.cpp:30:9: error: no matching member function for call to 'connect'
    connect(a, SIGNAL(signal(B*)), this, SLOT(slot(B*)));
    ^~~~~~~
/Users/Alexander/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qobject.h:198:36:
    note: candidate function not viable: 
        cannot convert argument of incomplete type 'A *' to 'const QObject *'
        static QMetaObject::Connection connect(const QObject *sender, const char *signal,
  

Почему это происходит?

Я использую QT 5.3.

Спасибо.

p.s. Извините за мой английский.

Ответ №1:

Вероятно, хорошей идеей будет избавиться от всего мусора, чтобы понять, что происходит:

 class QObject {};
class A;

void connect(QObject*) {}

void f(A* a) {
    connect(a);
}

class A : public QObject {};

int main()
{
    A a;
    f(amp;a);
}
  

Это упрощенная версия того, что у вас есть, и она сталкивается с той же проблемой. Проблема в том, что в вызываемой точке он connect был объявлен A только вперед. Компилятор еще не знает, что A наследует от QObject . Определить и указать это можно только позже A . Чтобы это сработало, определение A должно предшествовать вызову to connect .