【问题标题】:Undefined reference to vtable. Trying to compile a Qt project对 vtable 的未定义引用。试图编译一个 Qt 项目
【发布时间】:2010-12-05 20:12:40
【问题描述】:

我正在使用Code::Blocks 8.02 和 mingw 5.1.6 编译器。编译 Qt 项目时出现此错误:

C:\Documents and Settings\The Fuzz\Desktop\GUI\App_interface.cpp|33|undefined 参考`地址簿的vtable'

文件地址簿.h:

 #ifndef ADDRESSBOOK_H
 #define ADDRESSBOOK_H

 #include <QWidget>

 class QLabel;
 class QLineEdit;
 class QTextEdit;

 class AddressBook : public QWidget
 {
     Q_OBJECT

 public:
     AddressBook(QWidget *parent = 0);

 private:
     QLineEdit *nameLine;
     QTextEdit *addressText;
 };

 #endif

文件地址簿.cpp:

#include <QtGui>
#include "addressbook.h"

AddressBook::AddressBook(QWidget *parent)
     : QWidget(parent)
{
    QLabel *nameLabel = new QLabel(tr("Name:"));
    nameLine = new QLineEdit;

    QLabel *addressLabel = new QLabel(tr("Address:"));
    addressText = new QTextEdit;

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(nameLabel, 0, 0);
    mainLayout->addWidget(nameLine, 0, 1);
    mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
    mainLayout->addWidget(addressText, 1, 1);

    setLayout(mainLayout);
    setWindowTitle(tr("Simple Address Book"));
}

【问题讨论】:

    标签: c++ qt qmake


    【解决方案1】:

    使用 Qt Creator 时:

    1. 构建 → 运行 qmake
    2. 构建 → 全部重建

    【讨论】:

    • 这个答案具有误导性。如果 OP 使用 Qt Creator,这是完全合理的,但 OP 只声明 Code::Blocks。据我所知,Code::Blocks 在构建菜单上没有 run qmake 选项,为什么会这样呢?我可以相信插件会添加这样的选项,但 OP 没有提到使用任何第三方插件。很可能 OP 仍然必须运行 qmake 但告诉他们使用可能不存在的菜单选项不会有帮助。
    • 正确,解决方案(不使用 Creator 时)否则只是从命令提示符运行 qmake
    • 运行 qmake 然后 make 以获得确切的效果 - 运行 make 只会生成 make 文件。实际上,这是一个误导性的名称。
    【解决方案2】:

    警告:如果您已有 .pro 文件,请勿这样做 - 您会丢失它!

    为了自动确保生成所有moc cpp文件,可以让qmake自动为你生成一个.pro文件,而不是自己写一个。

    运行

    qmake -project
    

    在项目目录中,qmake 将扫描您的目录中的所有 C++ 头文件和源文件以生成 moc cpp 文件。

    【讨论】:

    • 我的问题与 OP 完全相同,但在我的情况下,重新运行 qmake 并不能解决它。这只是部分解决方案,仅适用于某些人。
    • DarenW:检查带有类声明的标题是否列在 HEADERS 中。
    • DarenW:谢谢,它有帮助。我在考虑这个问题 3 个小时。它是什么?我没有手动编写qmake。它在qt中以某种方式存在漏洞,还是什么?当我们写得很好时,为什么它不编译?
    • 不要运行这个。这将清除您的 .pro 文件和其中的任何修改。单独运行qmake(从命令行或从 Creator 中的 Build 菜单)就足够了。
    • 这个答案是错误且危险的。就这样。除非您从头开始并且没有现有的 .pro 文件,否则您永远不必这样做!
    【解决方案3】:

    问题几乎可以肯定是您没有在生成的 moc_AddressBook.cpp 文件中编译或链接。 (它应该已经为你生成了——你在编译之前在你的代码上运行 Qt 的moc,对吧?)

    为了更彻底地回答,Q_OBJECT 宏向 Qt 的moc 工具发出信号,以创建一个额外的实现文件,其中包含支持QObject 的元信息系统所需的代码。如果你有任何信号或槽,它也会为它们做一些事情。

    另一种解决方案可能是删除 Q_OBJECT 宏。您可能不想这样做,但它会帮助解决眼前的问题,而且您提供的代码并不是绝对必要的。

    另外,我会注意到你的台词:

    #include "addressbook.h"
    

    应该是:

    #include "AddressBook.h"
    

    基于您在问题中呈现文件名的方式。

    【讨论】:

    • Windows 文件系统不区分大小写。
    • 即使在 Windows 上,您仍然应该尝试注意大小写...在 Unix 上签出项目并不得不手动修复这样的案例问题真的很烦人,因为 Windows 上的原始开发人员没有不在乎
    【解决方案4】:

    假设您使用 qmake 生成 Makefile,请确保在 .pro 文件的 HEADERS 变量中指定 AddressBook.h,例如

    HEADERS = AddressBook.h
    

    【讨论】:

    • 这个问题的实际答案,没有平台/ide具体讨论或原因,清晰可用。谢谢。
    • 使用 QTCreator,您可以使用项目的“Headers”部分并将文件添加到那里(它会将其添加到 .pro 中的 HEADERS 变量中)
    • QtCreator 可能会在您的 .pro 文件中的 HEADERS 变量的第二行添加您的头文件名。然后第一行将是“HEADERS += \”。这行不通。擦除第一个空条目并使其(在 OP 情况下):“HEADERS += AddressBook.h”
    【解决方案5】:

    对于 CMake 项目,将 CMAKE_AUTOMOC 设置为 ON,这解决了我的问题。

    #Find includes in corresponding build directories
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    # Instruct CMake to run moc automatically when needed.
    set(CMAKE_AUTOMOC ON)
    

    【讨论】:

      【解决方案6】:

      我在使用纯虚函数时得到了这个。例如,

      virtual void process();
      

      出现此错误,而

      virtual void process() = 0;
      

      让它消失了。

      对于在谷歌上搜索此问题的任何人,请检查是否定义了所有虚函数。 (通过“= 0”或源文件中的完整定义) 我正在使用带有 MinGW 编译器的 Netbeans。

      【讨论】:

      • 我在 Ubuntu 下使用 Qt Creator 1.3 时遇到了同样的问题,这对我有用。不过,我不知道根本问题是什么。
      【解决方案7】:

      我在使用 CLion 时遇到了同样的问题,并通过将这些行添加到 CMakeLists.txt 来解决它

      set(CMAKE_AUTOMOC ON)
      set(CMAKE_AUTOUIC ON)
      set(CMAKE_AUTORCC ON)
      

      https://www.jetbrains.com/help/clion/qt-tutorial.html#qt-setup-in-clion

      【讨论】:

        【解决方案8】:

        我遇到了同样的问题,但是一旦我在头文件而不是 .cpp 中定义了我的构造函数,错误就消失了。文件系统和 Makefile 部分“compiler_moc_header_make_all”中也缺少相应的 moc 文件。我运行了一个 qmake,最后一切都成功了。我去检查了 Makefile,它现在就在那里。

        【讨论】:

          【解决方案9】:

          删除构建文件夹,重新启动 Qt Creator 并且它工作了

          【讨论】:

          • 这可能很好对你有用,但是鉴于 OP 没有使用 Qt Creator,它并不真正相关。
          【解决方案10】:

          我遇到了同样的问题,重建项目从不更新 Makefile,我删除了 Makefile 并重新构建,问题就消失了。 ps:从命令行运行'make'可能会给你比IDE更详细的信息,并且有助于解决真正的问题。

          【讨论】:

            【解决方案11】:

            一个原因是当你在一个类中声明一个虚函数而你没有定义它们的主体。

            【讨论】:

              【解决方案12】:

              在我的情况下,Rebuild All 还不够,我不得不删除构建目录并重新构建全部 - 然后它工作了!

              【讨论】:

              • 谢谢!我也遇到了同样的情况。
              【解决方案13】:

              您的项目只需 Run qmake。这可以通过右键单击项目名称并单击 Run qmake 轻松完成。

              【讨论】:

                【解决方案14】:

                只需清除项目,然后重建它!

                【讨论】:

                  【解决方案15】:

                  转到 .pro 文件并确保 .h 文件前面有“包含”。 标题 += 包含/file.h \ 包含/file2.h

                  【讨论】:

                    【解决方案16】:

                    我在尝试使用受保护的虚函数时遇到了同样的问题。有两件事奏效了。

                    1. void process(); 更改为void process() = 0;
                    2. process() 设为公开而不是私有

                    【讨论】:

                      【解决方案17】:

                      如果您不小心添加了析构函数原型,您将收到相同的错误消息。添加一个空的析构函数定义或删除原型。

                      【讨论】:

                        【解决方案18】:

                        moc 编译的头文件应该包含在 HEADERS += ... 变量中:

                        我已将 Myproject.pro 中的头文件移动到 SOURCES += ... 部分,因为我希望 mySource.h 和 mySource.cpp 在同一个树元素中。但这对 QT Creator 来说是错误的。结果出现错误“未定义对 vtable 的引用”。 好像是: QT 仅在 HEADERS +=... 部分(或变量)中检测 moc 编译的标头。 另请参阅other stackoverflow answer 第二个答案中的正确解释“我已经看到了很多解决问题的方法,但没有解释为什么会发生,所以就这样吧。”。在我看来,这是对问题的准确解释,它帮助我找到并解决了我的问题。

                        【讨论】:

                          【解决方案19】:

                          CMake

                          使用 CMake 时,有趣的是,如果我的 .cpp 和 .h 文件不在同一个文件夹中,则 moc(bu 默认)无法生成元文件 :)

                          【讨论】:

                            【解决方案20】:

                            我正在使用 Qt creator 来编译和运行我的程序,我不经常使用 Qt 命令提示符。我为摆脱恼人的错误“vtable something something”所做的一件事是将以下几行添加到.pro 文件中。

                            模板 = 应用程序

                            QT += 核心

                            【讨论】:

                            • 我认为这对您有用,只需使.pro 文件比Makefile 更新,从而导致重新qmake。这会重新生成依赖项,以便 moc 输出链接到应用程序。
                            猜你喜欢
                            • 1970-01-01
                            • 2021-11-30
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2012-08-14
                            相关资源
                            最近更新 更多