3

重複の可能性:
Qt: シグナルとスロット エラー: `vtable for への未定義参照

ここに test.cpp があります:

#include <QApplication>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

新しいディレクトリに単独で配置し、次のようにします。

$ qmake -project
$ qmake
$ make

それは動作しません:

test.o: In function `MainWindow::~MainWindow()':
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0x3): undefined reference to `vtable for MainWindow'
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0xb): undefined reference to `vtable for MainWindow'
test.o: In function `main':
test.cpp:(.text.startup+0x48): undefined reference to `vtable for MainWindow'
test.cpp:(.text.startup+0x51): undefined reference to `vtable for MainWindow'
test.o: In function `MainWindow::~MainWindow()':
test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0x7): undefined reference to `vtable for MainWindow'
test.o:test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0xf): more undefined references to `vtable for MainWindow' follow
collect2: error: ld returned 1 exit status
make: *** [tmp] Error 1

一般に、このようなエラーは、 moc が呼び出されていないか、実装されていない仮想メソッドが原因です。

moc は qmake によって自動的に呼び出される必要があり、私の知る限り、QMainWindow には純粋な仮想メソッドがありません。ここでの問題は何ですか?

Q_OBJECT を削除すると動作します。どうしてこれなの?何が起こっている?

Q_OBJECT がそのオブジェクトのシグナル/スロット メタデータを生成するように moc に指示していることがわかります。この場合、なぜそれができないのでしょうか?

アップデート:

#include "test.moc"解決策は、クラスのすぐ下に追加することです:

#include <QApplication>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
};

#include "test.moc"  // <----------- HERE

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
4

1 に答える 1

10

これは、.cpp ファイル内でクラスを宣言したためです。別の .h ヘッダーに入れます。

デフォルトでは、MOC はソース ファイルに対しては呼び出されず、ヘッダーに対してのみ呼び出されます (編集: @Kamil によると、MOC は .cpp ソース ファイルに対して実行されますが、生成された .moc ファイルは#include.cpp ファイルで手動で -d する必要があります - -以下の私の編集を参照してください)。

次に、それぞれのヘッダー ファイルを .pro ファイル内の HEADERS 変数に追加します。

もちろん、#include同じヘッダーを test.cpp に追加します。

また、こちらの回答を参照してください。

https://stackoverflow.com/a/5854884/1284631

編集:

このスレッドによると: http://www.qtcentre.org/threads/28580-Why-does-qmake-moc-only-process-header-files

.cpp ファイルに対して MOC の実行を強制するには、次を追加する必要があります。

#include "test.moc"

クラスの定義のすぐ下。そして、qmake を再実行します。ただし、これはテストしませんでした。

edit2:OPが探しているものに関する行の議論については、このリファレンスを参照してください:

http://harmattan-dev.nokia.com/docs/library/html/qt4/moc.html

于 2013-01-11T14:36:54.773 に答える