Development Tip

Q_OBJECT에서 'vtable에 대한 정의되지 않은 참조'오류 발생

yourdevel 2020. 11. 29. 12:23
반응형

Q_OBJECT에서 'vtable에 대한 정의되지 않은 참조'오류 발생


이 질문에 이미 답변이 있습니다.

Windows 7 Ultimate 32 비트에서 Qt 4.7.0 (32 비트)과 함께 Qt Creator 2.0.1을 사용하고 있습니다.

오류를 생성하기위한 최소값 인 다음 코드를 고려하십시오.

class T : public QObject, public QGraphicsItem
{
    Q_OBJECT

public:
    T() {}

    QRectF      boundingRect() const {return QRectF();}
    void        paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                      QWidget *widget) {}
};

int main()
{
    T t;
    return 0;
}

위 코드 조각으로 인해 다음 링커 오류가 발생합니다.

'T'함수에서 :

`vtable for T '에 대한 정의되지 않은 참조

`vtable for T '에 대한 정의되지 않은 참조

`~ T '함수에서 :

`vtable for T '에 대한 정의되지 않은 참조

`vtable for T '에 대한 정의되지 않은 참조

를 포함하는 줄을 주석 처리하면 Q_OBJECT잘 컴파일됩니다. 신호와 슬롯이 QGraphicsItem필요하므로 Q_OBJECT.

코드에 어떤 문제가 있습니까? 감사.


MOC에서 생성 한 단위는 연결 과정에 포함되지 않기 때문입니다. 또는 전혀 생성되지 않을 수도 있습니다. 가장 먼저 할 일은 클래스 선언을 별도의 헤더 파일에 넣는 것입니다. 아마도 빌드 시스템이 구현 파일을 스캔하지 않을 수도 있습니다.

또 다른 가능성은 문제의 클래스가 한때 Qt 메타 객체 시스템에 속하지 않았기 때문입니다 (즉, Q_OBJECT가 없거나 QObject에서 상속하지 않았을 수 있음). 따라서 qmake를 다시 실행해야 MOC에 필요한 규칙. qmake를 강제로 실행하는 가장 쉬운 방법은 공백을 추가 한 다음 제거하는 것과 같이 타임 스탬프를 업데이트하기 위해 프로젝트 파일을 약간 변경하는 것입니다. 또는 Qt Creator를 사용하는 경우 프로젝트 컨텍스트 메뉴에서 "Run qmake"를 선택하십시오.


QObject소스 파일에 하위 클래스 를 정의 하려면 다음 줄을 추가해야합니다.

#include "file.moc"

소스 파일의 이름이 file.cpp 인 클래스 정의 후 어느 시점에서. qmake물론 실행할 적절한 규칙 moc이 Makefile에 추가 되도록 다시 실행해야합니다 .

헤더 파일 Q_OBJECT에서 클래스 정의에 존재하는 경우에만 moc호출됩니다. 소스 파일 인 경우 강제 moc로 사용 하려면이 추가 라인이 필요합니다 .

이전에도 비슷한 질문이 있었지만 찾을 수 없었습니다.


Q_OBJECT 클래스를 별도의 파일에 넣으십시오. 그것은 각 클래스에 대해 하나의 .h와 하나의 .cpp입니다. Qt의 메타 객체 매크로는 이와 관련하여 다소 까다 롭습니다.

또한 목적에 맞게 QGraphicsObject사용할 수 있습니다 . 거기에서 시간을 절약합니다.

편집 : 당신이 Creator를 사용하고있는 것 같습니다. New File 또는 Project에서 New C ++ Class 함수를 사용하여 "올바른 방법"으로 파일을 만듭니다. :)


다음은 다른 질문에 제공된 모든 수정과 함께 추가 된 작업 코드입니다 (깨끗한 컴파일 시도 및 이러한 수정이 도움이 됨).

#include <QGraphicsItem>

class T : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem) //Required.

public:
    T() {}
    QRectF      boundingRect() const {return QRectF();}
    void        paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                      QWidget *widget) {}
};

int main(int argc, char *argv[])
{
    T *t = new T;
    return 0;
}

#include "main.moc" // Required.

그래서 Troubadour와 serge_gubenko에 대한 실제 신용


몇 가지 살펴볼 것이 있습니다.

  1. 프로 파일에 QT + = GUI 추가
  2. 헤더 파일에서만 QObject 파생 클래스를 정의해야합니다 (편집 : Troubadour가 언급했듯이 필수 사항은 아님).
  3. T 클래스 선언에 Q_INTERFACES (QGraphicsItem) 추가

아래는 예입니다.

일 :

class T : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)

public:
    T();
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

t.cpp :

T::T() {}

QRectF T::boundingRect() const
{
    return QRectF();
}

void T::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

위의 코드를 컴파일 해 보았지만 문제가 없었습니다.

이것이 도움이되기를 바랍니다.

참고URL : https://stackoverflow.com/questions/4774291/q-object-throwing-undefined-reference-to-vtable-error

반응형