错误C2027:使用了未定义类型

当在同一个源文件中定义了两个类,而两个类又相互之间进行引用(如方法中定义形参为另一个类的指针,方法体中通过指针引用成员)时就会报错:C2027:使用了未定义类型

该错误可以通过向前声明和单独编译方法解决,下面先介绍一下概念,再给出解决方法

前向声明: 可以声明一个类而不定义它,这个声明被称为前向声明(forward declaration)。 在声明之后,定义之前,类是一个不完全类型(incompete type),即已知向前声明过的类是一个类型,但不知道包含哪些成员。 不完全类型只能以有限方式使用,不能定义该类型的对象,不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。 可以通过编译的源文件就是一个编译单元,一个程序,可以由一个编译单元组成,也可以有多个编译单元组成 如:我们可以将所有东西都放在一个.cpp文件内,然后编译器就将这个.cpp编译成.obj,这就是一个编译单元 c++允许程序员将组件函数放在独立的文件中,可以单独编译这些文件,然后将它们链接成可执行的程序。 一个函数不能放到两个编译单元里面,但两个以上就可以分别放在一个单元,也就是cpp里面

一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),组成一个.exe,也就是程序了。

如果一个.cpp要用到另一个.cpp定义的函数只需在这个.cpp文件中写上他的函数声明(C++在同一个项目下的不同文件都位于全局作用域下,在其他文件中也可以引用)

两个类之间相互引用成员

在构造自己的类时,有可能会碰到两个类之间的相互引用问题 例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型
  1. 若是只是在两个类中相互使用了另一个类作为方法参数或其他只是定义该类型的指针及引用行为,使用向前声明即可解决

    不允许引用未定义类型:
    在这里插入图片描述
    使用向前声明解决:
    在这里插入图片描述

  2. 使用向前声明之后,在类定义之前,类是一个不完全类型(incompete type),即已知向前声明过的类是一个类型,但不知道包含哪些成员,所以在使用向前声明后,类定义前,只能定义指向该类型的指针及引用而不能使用该类成员

    在类定义之前不能使用类成员
    在这里插入图片描述

通过单独编译和向前声明方法实现两个类之间相互引用成员

向前声明的方法无法使用类的成员,那么只能使编译器知道这是自定义的类类型了

使用预处理指令include,将单独编译的文件引入到预处理命令include的地方

#include 命令是预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置;

C++在同一个项目下的不同文件都位于全局作用域下,在其他文件中也可以引用,如果一个.cpp要用到另一个.cpp定义的函数只需在这个.cpp文件中写上他的函数声明

通过将不同的类分隔成不同的类文件,不同的类将类声明和类定义分隔开,在需要使用其他类时引入目标类的头文件(引入声明)即可使用目标类

头文件声明

#pragma once
#include <iostream>
#include"SeparateCompilationClass1.h"//编译完成后,预处理器将文件的内容添加到程序中,该头文件就拥有了B类的完整声明
using namespace std;
class B;//使用向前声明,在编译器表示此为一个类类型,使头文件声明通过编译
class A {
public:
	void fun(B* b);//由于是声明,所以并不使用类成员,向前声明可以通过编译

源文件实现

#include"SeparateCompilationClass2.h"//A类的头文件,在其中引用了B的头文件,拥有B的完成声明,所以在本文件中可以使用B类成员
void A::fun(B* b) {//通过作用域运算符为A类添加成员定义
 cout << "A中的方法" << endl;
 cout << "使用B中成员:" << endl;
 b->fun();//通过单独编译可以使用B中成员
                    错误C2027:使用了未定义类型、两个类之间相互引用成员、向前声明错误C2027:使用了未定义类型向前声明单独编译两个类之间相互引用成员通过单独编译和向前声明方法实现两个类之间相互引用成员错误C2027:使用了未定义类型当在同一个源文件中定义了两个类,而两个类又相互之间进行引用(如方法中定义形参为另一个类的指针,方法体中通过指针引用成员)时就会报错:C2027:使用了未定义类型该错误可以通过向前声明和单独编译方法解决,下面先介绍一下概念,再给出解决方法向前声明前向声明:可以声明一个类而不定义它
				
在游戏的编写中,遇到了一个导入工程后运行出现”使用未定义“的错误。 绞尽脑汁也没搞懂是哪里出现了问题,看了其他人的blog后才发现了问题所在:定义的顺序 第一次错误代码如下:class Hp : public res{ private: int hpValue; //the value of hp this kind of medicine can provide; int n
如果不想犯下面错误最好的做法是,先把每一个都定义好后,再写函数实现部分(本例中将void A::funcA(B* inB)就放到了最后实现),写在前面的,需要使用后面的的时候只需要声明一下(像本例中的class B;放在A前一样),但使用的时候只能是以指针的形式出现!  注:其实把访问放到实现文件(CPP)中会自然避免这个问题,写到头文件中便不能访问成员且实现的代码也比较多,也不好实现成
最近在学习C++ 友元函数(成员函数做友元)这里遇到了一个小问题学习记录下(这个老师讲的超级好,推荐)。 想创建两个,Building和GoodGay,Building中设置公开访问的SittingRoom和私有的BedRoom,GoodGay中有两个函数 visit1() 和 visit2(),想把成员函数visit1(),设置为Building的友元函数来访问私有的BedRoom,但是却出现了问题,最开始的代码如下。 #include<iostream>
今天在添加了两个新的cpp和hpp文件后调试,结果编译器一直提示所使用的一个枚举类型未定义,经过仔细确认发现该类型已经正确定义,并且代码文件已经包含到工程中。 后来经过反复确认,再加上网友给的灵感,感觉可能是由于头文件循环引用导致的该枚举类型声明出现了异常!!!经过排查,发现确实如此!!!由于工程比较大,头文件的引用可能也不是很规范,头文件的层层嵌套引用导致出现了A.hpp包含了B.hpp,然后B.hpp又包含了A.hpp,故出现了上述未定义错误。 因此,当出现莫名其妙的类型未定义错误时,很可能是由于头文
#include "MyCharacter.h" #include <Camera/CameraComponent.h> //#include <Components/CapsuleComponent.h> // Sets default values AMyCharacter::AMyCharacter()
当我们在使用某些开源库或第三方库时,有时会遇到一些编译错误的情况,其中最常见的错误之一就是“未定义类型”。QextSerialPort是一个用于串口通信的开源库,通过其提供的API能够方便地实现串口通信功能。当我们在使用VS2019编译QextSerialPort库时,可能会遇到"C2027:使用未定义类型“QextSerialPortPrivate”"的错误。 这个错误是由于编译器找不到QextSerialPortPrivate这个类型所在的头文件。这时,我们需要检查一下代码中有没有对应的头文件。在这个库中,QextSerialPortPrivate是一个私有,它的定义在qextserialport_p.h这个头文件中。如果我们忘记将这个头文件包含在我们的代码中,编译器就找不到对应的类型,就会出现上述错误。 解决这个问题的方法很简单,只需要在你的项目中添加qextserialport_p.h这个头文件即可。另外,有时候可能还需要将该头文件所在目录添加到编译器的搜索路径中,这样编译器才能够找到该头文件。这些操作都可以在VS2019中通过添加到“属性管理器->VC++目录->包含目录”和“属性管理器->VC++目录->库目录”中实现。 综上所述,如果遇到VS2019 error C2027:使用未定义类型“QextSerialPortPrivate”的错误,需要检查代码中是否包含了对应的头文件,并且将该头文件所在目录添加到编译器的搜索路径中。