未解析的外部符号“ public: Virtual struct QMetaObject const *__ thiscall Parent

我从 QObject 继承了一个类:

class Parent: public QObject
{
Q_OBJECT
QObject* cl;


public:
Parent(QObject *parent=0):QObject(parent) {
cl = NULL;
}


QObject* getCl() const {
return cl;
}
void setCl(QObject *obj) {
cl = obj;
}
};

但当我写道:

Parent ev;

我得到以下错误:

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " (?metaObject@Parent@@UBEPBUQMetaObject@@XZ)


main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z)


main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Parent@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
96156 次浏览

您应该删除应用程序的 debug文件夹并再次运行它来纠正这个问题。

所以问题是我需要 Qt MOC 编译器来编译我的。H 档案。这对于扩展 QObject 或其子类之一的任何类都是必需的。这个修复包括(对我来说)右键单击头文件,选择 Properties,将 Item Type 设置为“ Qt MOC Input”,然后在头文件上点击“ Compile”,然后将得到的 MOC _ myfilename.cpp 文件添加到我的项目中。

如果使用 VisualStudio,请从头文件中删除 Q_OBJECT行,保存该文件,将 Q_OBJECT放回头文件中,然后再次保存该文件。这将生成 moc_*文件并正确构建和链接。

我注意到有些答案是基于 Visual Studio 的。

这个答案是基于 Qt Creator 的。

与名字所暗示的不同,Rebuild Project不会抹去一切,从头开始构建。如果您最近将 QObject(和/或 Q _ OBJECT)添加到您的类中,您将不得不再次运行 qmake,例如。

  1. 清洁工程
  2. 运行 qmake
  3. 构建项目

这是因为,默认情况下,qmake仅在对解决方案进行重大更改(如添加新源文件或修改 .pro文件)时运行。如果对现有文件进行编辑,它不知道需要运行 qmake

作为退路,强迫 Qt 从头开始构建一切,删除 DebugRelease文件夹。

在我的例子中(在 VS2012和 Qt v4.8.4中使用 QtAdd-In) ,上述建议都不起作用。 由于某些原因,VS 无法生成正确的 moc 文件(构建输出: 找不到相关类。没有产生任何输出。)当我手工编译相关的头文件时(设置 qt moc 为编译器并点击‘ Compile’) ,它会生成一个空的 moc 文件。

真正起作用的是从命令行(moc-o moc _ Some Class.cpp Some Class.h)编译所有必要的 moc,然后替换 GeneratedFiles 文件夹中错误的 moc。

这只是成功构建项目的变通方法(对于大型项目来说并不方便) ,但并不能真正解释奇怪的 VS/QtAdd-in 行为。

我使用 CMake 来管理 Qt 项目,新的 Q _ OBJECT 需要添加到 QT4 _ WRAP _ CPP 调用下。这将生成 moc _ * 。Cxx,以便包含在项目中,并清理未解决的外部事务。

在 VS2010中使用 QtAdd-in 实现了 moc _ * 。Cpp 文件在 GeneratedFiles/Debug 文件夹中更新,尽管我处于发布模式。将文件复制到发布文件夹对我来说很有效。

在使用“ PIMPL”(私有实现)编程模式时,我在 Qt 中使用“私有类”时遇到了这个问题。Qt 在整个源代码中都使用这个模型。我自己也开始喜欢上它了。

这种技术涉及到在公共头文件中使用一个“私有”前向声明的类,这个类将被“公共”类(即它的“父类”)使用。然后,父类有一个指向私有类实例的指针作为数据成员。

“ private”类完全定义在公共 cpp 文件中。没有私有类的头文件。

所有的“脏活”都是在那个私人班级里完成的。这将隐藏公共类的所有实现,通常包括其他每个私有成员(包括数据和函数)。

我强烈推荐学习 PIMPL 模式-特别是如果你正在阅读内部 Qt 源代码。

不需要进一步解释这种编码风格,下面就是与这个问题相关的要点... ... 让 Q_OBJECT宏在 cpp 中工作,让“私有”类成为可以使用信号/槽等的 QObject,您需要显式地将.moc 包含到 cpp 内的公共类中:

#include "MyPublicClass.moc"

您可以忽略关于此行的任何 IDE 警告。

我不确定这是否真的很重要,但是我总是在私有类定义之后看到包含,而不是在 cpp 的顶部(像 include 通常被放置)。Cpp 的布局是这样的:

  1. “正常”包括定义。
  2. 定义了私有类。
  3. 包含了公共类的 moc。
  4. 定义了公共类实现。

我最近从 MingW 转投 MSVC 时就遇到过这种情况。我将一个原型类/结构列为类,MingW 并不介意。

当涉及到原型时,MSVC 明确地看到了 classstruct之间的区别。

希望有一天能帮到别人。

如果您的 moc 文件是在可视化工作室项目中生成的,那么如果它们没有包含在项目中,则尝试将它们包含到项目中,然后重新生成。

对我来说,以上的方法都不管用,但这完全是我的错。

我在.h 文件中重写了虚函数(声明了它们) ,但从未在. cpp:)中定义过它们

我通过在头文件中添加以下内容解决了这个问题:

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H


... // all the header file content.


#endif

当我在 cpp 文件中有一个 Q _ OBJECT 类定义时,VisualStudio2012遇到了这个问题。将类定义移动到头文件解决了这个问题。

通过将 cpp 文件添加到 moc,似乎可以在 cpp 文件中支持 Q _ OBJECT 类,但我没有尝试这样做。

我手动将 cpp/ui 文件添加到项目中,但是忘记显式地将头文件添加为头文件。现在,在编译时,我得到了与上面相似的错误消息和 moc _ * 。没有在生成的调试(或发布)目录中生成 cpp 文件。这不是一个如此明显的错误,qmake 没有抱怨,除了链接器消息我没有得到任何错误。

因此,如果任何人再次遇到同样的问题(或作出相同的复制和关闭错误) : 确保头文件也已添加到项目文件中

在 VS 2013环境中,这两种答案对我都适用。我最终通过从项目中删除 。 h/.cpp 并将其添加回来解决了这个问题。

我在 Visual Studio 中遇到过同样的问题,并通过以下步骤解决了它:

  1. 在解决方案资源管理器中右击头文件
  2. 物业
  3. 将“项目类型”更改为“自定义生成工具”

然后在自定义构建工具配置中:

  1. 去总医院
  2. 将“命令行”设置为:

    "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fStdAfx.h" "-f../../../src/文件名" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION=7 -D_MATH_DEFINES_DEFINED "-I.\SFML_STATIC" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork"

  3. 将“输出”设置为:

    . GeneratedFiles $(ConfigurationName) moc _% (Filename) . cpp

  4. 将“附加依赖项”设置为:
    $(QTDIR) bin moc. exe;% (FullPath)


您的确切值可能不同。它们通常通过 Qt 插件应用。

我工作在 VS2015与一个集成的 Perforce p4v 客户端。 在我的例子中,Perforce 试图将 moc 文件添加到一个 Depo 中,当我恢复这个操作时,Perforce 从项目中删除了这个 moc 文件并将其删除。 这个文件是在下一次编译之后重新创建的,但是它没有包含在项目中,我必须手动将它添加到 Generated 文件中,这时我终于明白了问题所在。

我有同样的问题,我的解决方案是编码(我的文件“ UTF16LE BOM”不能生成与 moc. exe) ,y 创建另一个文件与 ASCII 结束和它的工作。

HxD HexEditor 可以帮助您查看编码。

我知道这是一个非常古老的问题,但它似乎仍然很有趣(我已经在过去的几个月里至少4或5次) ,似乎我找到了另一个原因,可能会得到这个错误。

在我的头文件中,我输错了:

#include "MyClass.h""

只有在检查了整个输出之后,我才发现编译器在那一行发出了警告。

现在,我删除了额外的引号,我的 QObject 编译完美!

对我来说,这是原因: 一些头文件或源文件不包括在 QT 的项目文件

我的问题是我的一个使用 Qt 宏的文件没有被 Moc 化。我发现,Qt Plugin for Visual Studio 不能识别 Q_NAMESPACE宏,因此不能将文件添加到 moc‘ ing 列表中。

所以我用 这个答案的解决方案把这个文件添加到麦克风列表中:

您应该找到一个. h 文件,它已经成功地生成了 “ moc _ *”,并复制“自定义构建工具-> 常规”中的所有内容 到新的.h 文件设置页面。

注意 DebugRelease模式的不同选项。

然后,构建您的项目。

DebugRelease模式下各建立一次

最后,将生成的“ moc _ *”文件添加到项目中。

现在,“ moc _ filename.cpp”应该位于 Generated Files\DebugGenerated Files\Release中。

右键点击它们,改变它们的属性:

  • Debug中的文件: 将配置更改为 Release,然后将 General->Excluded from build更改为 yes
  • Release中的文件: 将配置更改为 Debug,然后将 General->Excluded from build更改为 yes

Visual Studio 2017.

我已经添加了文件,已经设置了 Qt 项目,并得到了这个错误。我如何修复它:

在解决方案资源管理器中右键单击标题 属性... -> 配置属性-> 将军-> < em > 项类型 将 C/C + + 头更改为 < em > Qt 元对象编译器(moc)

瞧瞧

面临这个问题的情况下,链式 CMake 目标。事实证明,即使在没有直接使用 Qt (传递性)的目标中,我也必须启用 CMAKE_AUTOMOC。结果表明,CMAKE_AUTOMOC不能在同一母体的 CMakeLists.txtCMakeLists.txt中使用。

对我来说。H 和 the。Cpp 文件,用于项目子文件夹中有问题的 QObject 祖先。当我将它们移到 CMakeLists.txt (项目根文件夹)旁边时,它成功地链接了。我可能缺少一些 CMake 命令来在子目录中包含 mocs fot 文件。

当我删除 Q _ OBJECT 时,它工作得很好。

我使用的是 Clion + CMake + MSVC/14.31.31103。

是因为 Q _ OBJECT 在这些之后不再需要了吗?

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

用于 VisualStudio2022(带 Qt VS 工具扩展)

在解决方案资源管理器中,右键单击受影响的头文件并选择“属性”。
在“ Configurations Properties-> General-> Item Type”下选择“ Qt Meta-Object Compiler (moc)”选项。 那就重建项目。