为什么在链接Qt 5.0应用程序时会出现“undefined reference to vtable…”错误?

12

我有一个相对简单的Qt 5.0项目,使用的是CMake 2.8.9:

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
project(hello-world)

find_package(Qt5Widgets REQUIRED)
qt5_wrap_ui(hello-world_UI MainWindow.ui)

add_executable(hello-world MainWindow.cpp main.cpp ${hello-world_UI})
qt5_use_modules(hello-world Widgets)

MainWindow.h:

->

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

    public:

        MainWindow();
        virtual ~MainWindow();

    private:

        Ui::MainWindow * const ui;
};

#endif // CMAINWINDOW_H

MainWindow.cpp:

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow()
    : ui(new Ui::MainWindow)
{
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp:

#include <QApplication>
#include "MainWindow.h"

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

    MainWindow win;
    win.show();

    return app.exec();
}
该项目还包括一个使用Qt Creator 2.6.1创建的 .ui 文件(MainWindow.ui)。
在Linux上,当我尝试使用g++编译该文件时,会收到以下错误消息:
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow()': MainWindow.cpp:(.text+0x3b): undefined reference to `vtable for MainWindow' MainWindow.cpp:(.text+0x4d): undefined reference to `vtable for MainWindow' CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::~MainWindow()': MainWindow.cpp:(.text+0xaf): undefined reference to `vtable for MainWindow' MainWindow.cpp:(.text+0xc1): undefined reference to `vtable for MainWindow' collect2: error: ld returned 1 exit status
可能是什么原因导致这种错误?我最近从qmake切换到CMake,但我从来没有记得在编译一个微不足道的示例时遇到过这么多麻烦。我做错了什么?
编辑:这是用于链接所有内容的命令:
/usr/bin/c++ CMakeFiles/hello-world.dir/MainWindow.cpp.o CMakeFiles/hello-world.dir/main.cpp.o -o hello-world -rdynamic /usr/local/Qt-5.0.0/lib/libQt5Widgets.so.5.0.0 /usr/local/Qt-5.0.0/lib/libQt5Gui.so.5.0.0 /usr/local/Qt-5.0.0/lib/libQt5Core.so.5.0.0 -Wl,-rpath,/usr/local/Qt-5.0.0/lib
3个回答

21

结果我忘了:

set(CMAKE_AUTOMOC ON)

在CMakeLists.txt文件顶部。


2
我已经设置了(CMAKE_AUTOMOC ON),但我仍然看到与你看到的相同的错误。此外,我的链接命令与你的相同。你能帮忙吗? - Vaibhav Desai
1
此外,为目标“nova_app”生成的 moc 文件“nova_app_automoc.cpp”中包含以下内容: /* 此文件是自动生成的,请勿编辑 */ enum some_compilers { need_more_than_nothing }; - Vaibhav Desai
8
我遇到了几乎完全相同的问题,但是我已经在我的CMakeLists.txt中设置了(CMAKE_AUTOMOC ON),但是我仍然遇到了这个问题!! - Adam Miller
1
@AdamMiller 我知道这已经过时了,但如果有其他人遇到同样的问题,cmake需要知道在哪里找到头文件。在我将所有头文件与源代码一起使用GLOB之前,我也遇到了你所遇到的问题。通过详细构建,我可以看到automoc没有生成任何内容。 - regomodo
1
@regomodo,你真是救星!我忘记在CMake的add_library函数中添加头文件了。谢谢你。 - Saeed Masoomi

6
我曾经在这里发布的所有提示中努力解决了很长时间:

http://doc.qt.io/qt-5/cmake-manual.html

以及这里

https://www.kdab.com/using-cmake-with-qt-5/

我所做的就是按正确顺序指定事项。例如,以下是我的CMakeLists.txt的顶部。请注意,在add_executable之前,两个CMAKE设置指令都会出现。一旦我这样做了,我就能够链接而不会出现未定义的符号和vtable引用。我只是想为其他人提供帮助而发布这篇文章。

cmake_minimum_required (VERSION 2.8)

set (CMAKE_AUTOMOC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(FHSpectrumSensor wideband_seq_spectrum_sensor.cpp sensor.cpp   gui.cpp ${gui_SRC})

在CMakeLists.txt文件的后面,我有以下内容:

 find_package(Qt5Widgets REQUIRED)
 find_package(Qt5Charts REQUIRED)
 find_package(Qt5Core REQUIRED)

 qt5_use_modules(FHSpectrumSensor Widgets Charts)
 qt5_wrap_cpp(gui_SRC gui.h gui.cpp)

那可解决了。

1
对我有用,谢谢!问题通过 qt5_wrap_cpp(gui_SRC gui.h gui.cpp) 得到解决。实际上,我添加了 .h 文件而不是 gui.cpp,这就是问题所在。现在我将它们更改为 .cpp 文件,问题得到解决,谢谢。 - SdSaati

3
昨天我也遇到了这个问题,上面提到的答案没有帮助。我已经使用了set (CMAKE_AUTOMOC ON)qt5_wrap_cpp
我试图想起自己做了什么,因为我曾经有一个工作版本,但在“某些”更改后停止工作。最终我记得我试图将包含文件拆分到单独的目录层次结构中。在恢复之后,将包含文件放回CMakeLists.txt中,它再次工作。我当然不知道为什么,我想知道出了什么问题,但现在我已经决定将包含文件保持在cpp文件附近。
set(SOURCES
    buffer.h
    ITVSet.h
    MainWindow.h
    MainWindow.cpp
    TVSet.h
    TVSet.cpp
)

1
当您将 MainWindow.h 添加到 SOURCES 或者可以拆分为 project_HEADERS 时,该头文件将被包含在构建中,并且 moc 文件将为该头文件生成。 - Mohammad Kanan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接