Framework Qt 4.7. Проблема при формировании указателей виртуальной таблицы?

Начнем по порядку. Имеется описание некого класса, отвечающего за визуальное оформление программы.
#include <QtGui>
class Windows : public QObject
{
protected:
   friend class MyClass;

   QPushButton *but1;
   QPushButton *but2; 
public:
   Windows(QApplication *App);
   QPushButton *RUN;
}


В конструкторе этого класса производится инициализация всех полей. QApplication*App нужен для того, чтобы через сигнал нажатия кнопки “Close” произвести закрытие приложения.


Далее идет описание дружественного класса, в котором будет наблюдаться агрегирование ранее описанного класса по значению (композиция).
#include <windows.h>
#include <QFile>
#include <cstdlib>
class MyClass : public QObject
{
    Q_OBJECT
private:
    int number_of_lines;
public:
    MyClass (QApplication*App);
    Windows *win; // Объект, отвечающий за визуализацию
public slots:
    void myFunc(); 
}


Определение этого класса выглядит следующим образом:
MyClass:: MyClass (QApplication *App) // Конструктор
{
    win = new Windows (App);
}
void MyClass::myFunc()
{  }


В теле основной программы main.cpp содержится следующее:
#include "myclass.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyClass *c1 = new MyClass (&app);

    QObject::connect(c1->win->RUN, SIGNAL(clicked()),
                     c1, SLOT(myFunc()));
    return app.exec();
}


Тоесть, при нажатии кнопки RUN в окне программы, должна (по идее) запускаться функция myFunc() из объекта c1.


Когда в редакторе я запускаю компиляцию, то получаю следующую ошибку:

In function “MyClass”:

undefined reference to “vtable for Compiler”

(здесь ссылка на конструктор класса MyClass)

undefined reference to “vtable for Compiler”

(дублирует)

collect2: returned 1 exit status


Прошу помощи в решении данной проблемы. Уже пытался решить ее подобным способом месяц назад, но встретив такую ошибку, бросил эту затею. Работу продолжал по принципу: в main.cpp не ставил никаких связей, а напрямую вызывал функцию (не слот) из объекта:
#include "myclass.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyClass *c1 = new MyClass (&app);
    c1->myFunc();
}


Тоесть программа начинала перед запуском работать с функцией, а при нажатии кнопки RUN просто показывала окно с содержимым результата.
  • Вопрос задан
  • 2666 просмотров
Решения вопроса 2
Gorthauer87
@Gorthauer87
Программист
>MyClass:: MyClass (QApplication *App) // Конструктор

Мать моя женщина! qapp же синглтон! Friend классы в данном конкретном случае вообще не нужны и скорее вредны.И еще советую курить на тему moc'а, в main.cpp если очень хочется обьявить класс зависимый от QObject файла, то нужно писать в конце #include «moc_main.cxx» или же #include «main.moc»
И вообще, весь код совершенно не в духе Qt написан, а каким-то странным образом. Лучше почитать примеры кутишные для начала и в доках соглашения о кодировании!
Ответ написан
bfDeveloper
@bfDeveloper
В коде есть нарушение двух правил наследования от QObject:
1) Макрос Q_OBJECT надо писать всегда. Допускается использование без него, но это только если вы в этом уверенны на 100% и понимаете, как это работает. В официальной доке по Qt настоятельно рекомендуется писать этот макрос всегда, когда наследуете QObject.
2) Конструктор наследника QObject должен иметь вид:
explicit MyObject(..., QObject* parent=0);
Это требуется для реализации объектных иерархий.

Кроме того, в конструкторах ваших классов нет вызова конструктора предка, т.е QObject(parent).

Не уверен, что что-то из этого приводит к вашей ошибке, однако так, как написано у вас, писать точно не стоит.

Кстати, бывает, что возникают проблемы, когда класс, который не был наследником QObject в процессе разработки им становится. QtCreator не всегда соображает правильно и не запускает qmake после этих исправлений. Попробуйте запустить qmake руками и потом пересобрать проект.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы