C++ 类的前置声明

最近在仿照muduo的网络库源代码写自己的网络服务器,当初想着整个项目分模块去写,最后再和主程序链接,正好升入理解一下编译链接的过程,但是现在发现每个模块的内容其实也不是很多,实际上没有必要分模块去写。然后在写的过程中就遇到了一些问题,困扰了我很久,那就是前置声明问题 这个问题开始于一个头文件的循环引用

现在有两个头文件

  • 头文件a.hpp

    #include"B.hpp"
    // a.hpp
    class A {
    public:void printA();B b;
    };
    

    这个类A中有一个定义了一个自定义类型B,这个B类型使我们定义的类

  • 头文件b.hpp

    #include"A.hpp"	
    class B {
    public:void printB();A a;
    };
    

​ 这个类B中有一个自定义类型A

上面两个头文件就造成了非常难搞的问题,两个类相互依赖,且在两个不同的文件里面,于是我那时候想当然的就写出了以下代码上面的代码,然后在编译的时候就会出现大问题!!

让我们复习一下编译的过程:

  • 预编译
  • 编译
  • 汇编

然而在预编译的时候会做一步重要的处理就是头文件展开,而这个展开的过程是递归进行的,也就是说你展开的头文件里面可能引用了别的头文件,全部都要展开直到没有#include为止

所以我们只看头文件B.hpp,我们先展开他的头文件A.hpp(因为B.hpp引用了A.hpp),展开效果如下:👇

#include"B.hpp"
// a.hpp
class A {
public:void printA();B b;
};
class B {
public:void printB();A a;
};

如果照这样继续展开下去,你就会发现这实际上是一个无穷无尽的过程,所以编译过程会一直循环不会停止。那么这个问题该如何处理呢?

这就要用到C++类的前置声明了,实际上这个的逻辑就是我不引头文件,而是在你前面先写一个类的声明(注意是声明不是定义)

B.h

class A;
class B {public:    void printB();A a;
};

A.h

class B;
class A {public:    void printA();B b;
};

这样所有的问题似乎得到了解决。但这样你去编译的时候还是会报错,原因就是另外一个坑:前置声明 之后只能定义指针和引用,而不能定义出一个实体类。

所以下面的定义才是正确的:

B.h

class A;
class B {public:    void printB();A* a;
};

A.h

class B;
class A {public:    void printA();B* b;
};

最后在A 和 B的定义文件(也就是cpp文件中)每个的定义文件分别引入#include"A.h"#include"B.h"然后在定义A或B的成员函数既可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/89542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将48位立即数加载到ARM通用寄存器中?

安全之安全(security)博客目录导读 问题:如何将48位立即数加载到ARM通用寄存器中? AArch64执行状态中支持的指令集称为A64。所有A64指令的宽度都是32位。Move(宽立即数)被限制为16位立即数。 如果使用以下指令将一个48位的值赋给一个通用寄存器,会得到…

【EI会议征稿】第八届能源系统、电气与电力国际学术会议(ESEP 2023)

第八届能源系统、电气与电力国际学术会议(ESEP 2023) 2023 8th International Conference on Energy System, Electricity and Power 第八届能源系统、电气与电力国际学术会议(ESEP 2023)定于2023年11月24-26日在中国武汉隆重举…

【斯坦福cs324w】中译版 大模型学习笔记十 环境影响

环境影响 温室气体排放水足迹:数据中心使用水进行冷却;发电需要用水释放到环境中的化学物质很多是对人类有害的 如何计算数据中心能源消耗 简单表示形式 模型训练过程 参考资料 datawhale so-large-lm学习资料

PostGreSql中统计表中每天的数据,并统计每天的回复数,未回复数以及未回复占比(显示百分比)

前言 要在 PostgreSQL 中统计表中每天的数据,并统计每天的回复数、未回复数以及未回复占比,并以百分比形式显示,你可以使用以下 SQL 查询。假设你有一个名为 "messages" 的表,其中包含消息的时间戳列 "timestamp&…

【MySQL】如何配置复制拓扑?

前言配置大框架配置复制主服务器(master)配置复制从属服务器(slave)复制过滤规则感谢 💖 前言 关于MySQL中的复制技术相关内容,可以看看这些文章: 【MySQL】MySQL中的复制技术是什么&#xff1…

英语——谐音篇——单词——单词密码

记忆即联结,只要能建立有效的联结,就能很好地记住。在现实生活中,声音的联结模式能很好地帮助我们记忆。几乎每个学生都曾用谐音的方法记忆一些事物,但很多人都没有意识到,我们每个人都可以通过一定的练习,…

超声波乳化具有什么特点(优点)?

梵英超声(fanyingsonic)探针式超声波乳化棒 超声波乳化是通过探针式超声波探头,高强度超声波耦合到液体中并产生声空化。超声波或声空化产生高剪切力,提供将大液滴破碎成纳米尺寸液滴所需的能量。梵英超声(fanyingsonic)提供各种探头式超声波乳化棒和配件…

skywalking 整合

安装sw docker 安装, compose 11800是外侧服务向skywaling投送数据的接口 12800是用来和web界面交互数据的接口 8080是ui界面商品 安装后,访问8080 怎么接入服务 下载 基于java的探针技术自动的上报指标数据,不用改源代码 要改下配置 后端…

与机器学习相比,人类的学习包括视觉、听觉、触觉、嗅觉、味觉的串并行混合学习...

视觉学习、听觉学习和触觉学习是人类感知和认知过程中的三个重要方面。 视觉学习:视觉学习是通过视觉感知信息进行学习和认知的过程。人类视觉系统能够感知并解读光线的反射或发射,从而获取关于物体、场景和环境的信息。视觉学习涉及识别、分类、空间感知…

Linux系统文件的三种time(atime/ctime/mtime)

使用Go操作文件,根据创建时间(或修改时间)进行不同处理。 在Mac上,文件相关的结构体字段在syscall/ztypes_darwin_arm64.go下的Stat_t: type Stat_t struct {Dev int32Mode uint16Nlink uint16Ino uint64Uid …

微信小程序页面栈超出导致页面卡死

微信小程序页面栈不能超出10个 超出10个之后无法进行点击选择跳转 解决方法: 跳转的时候,判断之前页面栈里是否存在要跳转的页面, 如果存在之前页面,就navigateBack返回之前页面, 如果不存在之前页面,判断…

精通git,没用过git cherry-pick?

前言 git cherry-pick是git中非常有用的一个命令,cherry是樱桃的意思,cherry-pick就是挑樱桃,从一堆樱桃中挑选自己喜欢的樱桃,在git中就是多次commit中挑选一个或者几个commit出来,也可以理解为把特定的commit复制到…

xyhcms getshell

下载xyhcms3.6.2021版本并用phpstudy搭建 function get_cookie($name, $key ) {if (!isset($_COOKIE[$name])) {return null;}$key empty($key) ? C(CFG_COOKIE_ENCODE) : $key;$value $_COOKIE[$name];$key md5($key);$sc new \Common\Lib\SysCrypt($key);$value $sc-…

中国沿海水产养殖空间分布数据集(1990-2022)

4年间隔的遥感信息提取中国沿海水产养殖空间分布数据集(1990-2022) 人口增长引起水产品需求快速增加,而野生捕捞产量受环境承载力的限制趋于饱和,这使得水产养殖业在过去数十年间迅速发展。水产养殖能够有效保障人类粮食安全和营养…

Web自动化测试 —— headless无头浏览器!

一、Options概述 是一个配置浏览器启动的选项类,用于自定义和配置Driver会话常见使用场景: 设置无头模式:不会显示调用浏览器,避免人为干扰的问题。设置调试模式:调试自动化测试代码(浏览器复用) 二、添加启动配置 添…

谈谈前端和后端的选择

引言 在我的印象中,也是视线里,后端都是在一个黑屏的页面,左边一个文件类,右边在不停的写sql,一只手放在键盘上,一边写,一遍不停的关联进入,感觉很无趣,他们的分享不是什么java集成&…

Java分支结构:一次不经意的选择,改变了我的一生。

👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、顺序结构二、分支结构1、if语句2、switch语句 好久不见!命运之轮常常在不经意间转动,有时一个看似微…

静态通讯录

今天我们分享一下静态通讯录详细解释和代码,之前分享过的只是通讯录的代码,但是我们没有进行讲解和解释,今天我们一边分享它的代码一边解释原因,让大家可以手撕通讯录。现在开始我们的学习吧。 首先我们应该要有三个文件&#xf…

MYSQL8解压版 windows 主从部署步骤及配置(包含配置文件,教程文件,免积分下载)

MYSQL8解压版 windows 主从部署步骤及配置 一.安装MSYQL 这里只讲大概,详细步骤、my.ini文件、安装包等会在页尾文件中(正常情况按首个mysql安装,只是名字有区别) 1.主库my.ini配置 [mysqld] #典型的值是5-6GB(8GB内存),8-11GB(16GB内存), 20-25GB(32GB内存)&…

Ctfshow web入门 XSS篇 web316-web333 详细题解 全

CTFshow XSS web316 是反射型 XSS 法一&#xff1a; 利用现成平台 法二&#xff1a; 自己搭服务器 先在服务器上面放一个接受Cookie的文件。 文件内容&#xff1a; <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt"…