【C++】错误C2027:使用了未定义类型错误原因 两个类之间怎么相互使用成员 向前声明概念
错误C2027:使用了未定义类型、两个类之间相互引用成员、向前声明
- 错误C2027:使用了未定义类型
- 向前声明
- 单独编译
- 两个类之间相互引用成员
- 通过单独编译和向前声明方法实现两个类之间相互引用成员
错误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定义的类型
若是只是在两个类中相互使用了另一个类作为方法参数或其他只是定义该类型的指针及引用行为,使用向前声明即可解决
不允许引用未定义类型:
使用向前声明解决:
使用向前声明之后,在类定义之前,类是一个不完全类型(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中成员}
【C++】错误C2027:使用了未定义类型错误原因 两个类之间怎么相互使用成员 向前声明概念相关推荐
- 重复包含定义 导致未定义类型不识别错误
错误提示: f:\vs2010projects\combine\combine\func.h(9): error C2011: "func":"class"类型 ...
- MDK:assert_param函数未定义的错误:Error: L6218E
今天使用奋斗stm32开发板,编译程序时 出现了一下错误,网上有很多解决方案,可是一直没解决, 在链接过程中出现assert_param函数未定义的错误:Error: L6218E: Undefine ...
- vue-cli项目布署问题解决:空白页、静态资源文件404错误、refrenceError:promise未定义(部分浏览器不支持ES6语法)
(前言:文章记录vue-cli项目打包使用IIS布署遇到的几个错误及解决方式) 首先简单理解webpack打包: 个人理解:项目开发中我们构建 "低耦合高内聚" 的组件/模块来代码 ...
- 对 mysql_init 未定义的引用_解析:以mysql_开始的未定义引用错误
当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ccFKsdPa.o: 在函数`main'中: /tmp/ccFKsdPa.o(.te ...
- mysql未定义_以mysql_开始的未定义引用错误
以mysql_开始的未定义引用错误 作者:佚名 来源:CNZZ 2008-12-26 当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ ...
- mysql未定义_以mysql_开始的未定义引用错误_MySQL
以mysql_开始的未定义引用错误_MySQL 作者:小涵 | 来源:互联网 | 2018-04-19 15:15 阅读: 1682 以mysql_开始的未定义引用错误 当你链接到应用程序以使用MyS ...
- mysql未定义_解析:以mysql_开始的未定义引用错误
当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ccFKsdPa.o: 在函数`main'中: /tmp/ccFKsdPa.o(.te ...
- 在编译内核的最后阶段出现sdhci_esdhc_imx_pdata未定义的错误
遇到下面这种错误 在网上查找资料后,发现一篇好文,提出了良好的找错误的策略: (1)利用grep命令查看该变量在何处使用: (2)查看相应的头文件是否在Kconfig中被定义且在make menuco ...
- java方法未定义类型_java - 方法未定义为类 - SO中文参考 - www.soinside.com
我试图在eclipse中运行一个使用名为getArea(一个对象)的方法的代码.我目前收到错误说 对于getArea(ComparableRectangle)类型,方法RectangleTest未定义 ...
最新文章
- vue.js 第四课
- .NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)...
- 信号量与条件变量的区别
- 自然语言处理应用和过程的一些理解
- sqlserver 批量处理数据
- android 网络调试 源代码,Android源代码调试环境搭建
- JAVA spring 常用包作用详解(转)
- thinkphp5.x之数据库操作相关解析 Db类
- ResultSet用法集锦
- 修改tomcat日志打印位置
- 服务器器ip的A段B段C段是什么意思有什么意义
- 拿下国产高端市场第一背后,vivo与苹果、华为的共性
- 电视hdr测试软件,HDR是什么意思 如何打开电视机的HDR10模式
- 蜂鸣器电路设计中选用注意事项--【电路设计】
- 2021秋季《数据结构》_EOJ 1086.哥尼斯堡的七桥问题
- centeros 卸载mysql_如何卸载数据库centeros
- 华为手机如何连接到电脑
- Altium Designer19(AD19)
- 凯斯西储大学轴承数据介绍及处理
- NBA勇士陷入苦境 威金斯不保证这季会归队
热门文章
- python12306登录_python 手动验证并模拟登录12306
- nginx的防盗链,动静分离,缓存,负载均衡,反向代理
- tez引擎跑hive 语句报错问题解决
- windows 设置exe文件开机自启动
- javascript 面向对象(实现继承的几种方式)
- 基于概率论的分类方法: 朴素贝叶斯
- Pdf文件怎么翻译,翻译pdf文件的两个好办法
- LibreSSL SSL_read: error:02FFF03C:system library:func(4095):Operation timed out, errno 60
- 安信可TB系列低功耗蓝牙模块选型表
- C# xlsx转csv