Qt неопределенная ссылочная виртуальная таблица

Я сделал простую игру, чтобы выстрелить в прямоугольник (класс Bullet) из другого прямоугольника (класс MyRect). У меня есть неопределенная ссылка на "vtable для пули". Я написал, что это связано с Q_OBJECT и moc. Не могу решить эту проблему.

Пуля.ч

#ifndef BULLET_H
#define BULLET_H
#ifndef Q_MOC_RUN


#include <QGraphicsRectItem>
#include <QObject>



class Bullet: public QObject,public QGraphicsRectItem{
    Q_OBJECT
public:
    Bullet();
public slots:
    void move();
};

#endif
#endif // BULLET_H

MyRect.h

#ifndef MYRECT_H
#define MYRECT_H

#include <QGraphicsRectItem>

class MyRect: public QGraphicsRectItem{
public:
    void keyPressEvent(QKeyEvent* event);
};

#endif // MYRECT_H

Bullet.cpp

#include "Bullet.h"
#include <QTimer>

Bullet::Bullet(){

    setRect(0,0,10,50);   
    QTimer * timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(move()));

    timer->start(50);
}

void Bullet::move(){

    this->setPos(x(),y()-10);
}

main.cpp

#include <QApplication>
#include <QGraphicsScene>
#include "MyRect.h"
#include <QGraphicsView>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene * scene = new QGraphicsScene();

    MyRect * rect = new MyRect();
    rect->setRect(0,0,100,100);

    rect->setFlag(QGraphicsItem::ItemIsFocusable);
    rect->setFocus();

    scene->addItem(rect);
    QGraphicsView * view = new QGraphicsView(scene);

    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    view->show();
    return a.exec();
}

MyRect.cpp

#include "MyRect.h"
#include<QKeyEvent>
#include <QGraphicsScene>
#include "Bullet.h"
#include<QDebug>

void MyRect::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Left)
    {
        setPos(x()-10,y());
    }
    else if(event->key() == Qt::Key_Right)
    {
        setPos(x()+10,y());
    }
    else if(event->key() == Qt::Key_Up)
    {
        setPos(x(),y()-10);
    }
    else if(event->key() == Qt::Key_Down)
    {
        setPos(x(), y()+10);
    }
    else if(event->key() == Qt::Key_Space)
    {
        Bullet * bullet = new Bullet();
        bullet->setPos(x(), y());
        scene()->addItem(bullet);
    }

}

Я написал аналогичную ошибку в Qt, но все равно не могу решить ее. Большое спасибо за внимание.


person Paweł    schedule 03.05.2020    source источник
comment
После qmake у вас все еще есть ошибка?   -  person thibsc    schedule 04.05.2020
comment
Я не менял qmake. Я определяю q_moc_run. У меня нет ошибки, но мой прямоугольник (пуля) не меняет положение   -  person Paweł    schedule 04.05.2020
comment
Я думаю, что эта пуля пока не MyRect, потому что я добавлю картинку (отличную от пули и MyRect, которые стреляют)   -  person Paweł    schedule 04.05.2020
comment
Не знаю, зачем вы ставите макрос Q_MOC_RUN, удалите его и протестируйте, у меня работает   -  person thibsc    schedule 04.05.2020
comment
Скорее всего: убедитесь, что Bullet.o включено в команду ссылки. Неопределенная ссылка на сообщение vtable превалирует над любым сообщением о неопределенной ссылке на конструктор Bullet.   -  person JaMiT    schedule 04.05.2020
comment
Отвечает ли это на ваш вопрос? Неопределенная ссылка на vtable   -  person JaMiT    schedule 04.05.2020
comment
Я выбрал вариант очистить все и запустить в QT Creator, и теперь он работает   -  person Paweł    schedule 04.05.2020


Ответы (1)


Я получил такую ​​​​же ошибку с этим оператором в базовом классе.

virtual void setInitiator(QPainter* painter, QImage* image);

Неопределенная ссылка на 'vtable for FractalObject'

FractalObject — мой базовый класс.

Я получаю классы, которые используют функцию-член, но в базовом классе нет реализации. Чтобы все исправить, мне нужно было сделать следующее:

virtual void setInitiator(QPainter* painter, QImage* image) = 0;

Я предполагаю, что присваивание нулю приводит к созданию виртуальной таблицы, которая содержит нулевой указатель на функцию-член. Это простое задание все исправило для меня.

person Keith    schedule 14.12.2020