C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(1)

        在使用模块之前,头文件用于提供代码重用的接口。头文件确实有许多问题,比如避免同一头文件的多重包含以及确保头文件的包含顺序正确。还有,简单的#include,例如,<iostream>就添加了几千行代码,编译器不得不编译。如果几个源文件#include <iostream>,所有这些翻译单元变得更大了。这还只是包含了一个简单的头文件。想像一下,如果需要<iostream>,<vector>,<format>等等。

        模块解决了所有这些问题,甚至更多。模块被import的顺序并不重要。模块一旦被编译为进制格式,每当该模块被import进行另一个源文件时,编译器就可以使用。这与头文件是一个明显的对比,头文件是每当编译器碰到#include那个头文件时都要进行一而再再而三的编译。因此,模块可以极大节省编译时间。当在模块中修改了内容时,也节省了增加的编译时间,例如,修改一个模块接口文件中的导出函数实现,不需要触发使用那个模块的用户的重新编译。模块不受外部定义宏的影响,任何在模块中定义的宏对模块之外的任何代码不可见,也就是说,模块是自我隔离的。因此,推荐如下:

        注意:有了以上讨论的好处,如果编译器支持模块,新写的代码应该使用模块来结构化代码成为逻辑上分隔的构造块。

        如果可能的话,历史遗留代码也可以慢慢转换为模块。然而,遗留代码太多了,许多第三方库还不支持模块,现在也不是所有的编译器完全支持模块。基于这些原因了解传统的头文件是如何工作的依然重要。这就是本章仍然要包含头文件的讨论的原因。

        注意:如何编译模块与编译器相关。咨询编译器的文档来学习特定编译器的模块工作方式。

        注意:如果你的编译器不支持模块,那就只能将我们的例子转化为非模块的代码了,但还是建议你与时俱进,跟上时代的脚步吧,找一个支持模块的编译器,使你的工作事半功倍;而不是因循守旧,事倍功半。

1、将代码非模块化

        如果想要使用还不完全支持模块的编译器来编译本博客中的代码,可以按如下步骤将代码非模块化:

  • 重命名.cppm模块接口文件为.h头文件。
  • 在每个.h头文件的顶部添加#pragma once。
  • 去除export module xyz声明
  • 替换module xyz声明为#include来包含相应的头文件。
  • 替换import与export import声明为合适的#include指令。如果代码使用了import std;那就需要用#include指令来包含所有需要的单个头文件了。
  • 去除任何export关键字。
  • 去除所有的module;,它指出了全局模块部分的开始。
  • 如果函数定义或变量定义出现在一个.h头文件中,在前面添加inline关键字。

2、标准命名的模块(c++23)

        通过导入标准命名模块std可以访问c++标准库的任何东东。该命名模块使得整个标准库可用,包括所有的定义在<cstddef>中的C功能。然而,只要通过std命名空间就可以使用所有的C功能。对于遗留代码,可以考虑导入std.compat命名模块,它导入了所有的std import的,同时使得std命名空间与全局空间的C功能可用。在新的代码中不推荐使用std.compat。

3、模块接口文件

        模块接口文件定义了由模块提供的功能的接口,通常以.cppm作为文件扩展名。模块接口文件以声明标示文件是由一个特定的名字定义的模块开头。这叫做模块声明。模块名字可以是任何合法的c++标识符。名字可以包含.但是不能以.开始或结束,并且不能一行中包含多个.。合法的名字的例子是datamodel,mycompany.datamodel,mycompany.datamodel.core,datamodel_core,等等。

        注意:目前,还没有模块接口文件的标准扩展名。然而,大多数编译器支持.cppm(C++模块)扩展名,所以我们也这么用。可以检查一下你的编译器使用的是什么样的扩展名。

模块需要显式声明要把什么导出去,也就是说,当客户端代码导入模块时什么是可见的。模块可以导出任何声明,例如变量声明,函数声明,类型声明,using指令,以及using声明。还有,导入声明也可以被导出。从模块中导出实体通过export关键字来完成。从模块中没有导出的东东只在模块自身内可见。所有导出的实体的集合叫做模块接口。

        下面是一个模块接口文件的例子,名字叫做Person.cppm,定义了一个person模块,导出了一个Personal类。注意,它导入了由std提供的功能。

export module person;    // Named module declarationimport std;                // Import declarationexport class Person        // Export declaration
{
public:explicit Person(std::string firstName, std::string lastName): m_firstName{ std::move(firstName) }, m_lastName{ std::move(lastName) } { }const std::string& getFirstName() const { return m_firstName; }const std::string& getLastName() const { return m_lastName; }private:std::string m_firstName;std::string m_lastName;
};

        在标准术语中,所有东东以命名模块声明开始(上面代码段中的第一行),直到文件结尾,叫做模块范围。

        Person类可以通过导入person模块来使用,如下(test.cpp):

import person;
import std;using namespace std;int main()
{Person person{ "Kole", "Webb" };println("{}, {}", person.getLastName(), person.getFirstName());
}

        任何东东都可以从模块导出,只要它有名字。例子为类定义,函数原型,类枚举类型,using声明与指令,命名空间,等等。如果命名空间使用export关键字显式导出,该命名空间中的所有东东也自动导出。例如,下面的代码段导出了整个DataModel命名空间;因此,没有必要再显式导出单个类与类型别名:

export module datamodel;import std;export namespace DataModel
{class Person { /* ... */ };class Address { /* ... */ };using Persons = std::vector<Person>;
}

        也可以使用export block导出一个声明的整块,下面是一个例子:

export
{namespace DataModel{class Person { /* ... */ };class Address { /* ... */ };using Persons = std::vector<Person>;}
}

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

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

相关文章

第十五章 Vue工程化开发及Vue CLI脚手架

目录 一、引言 二、Vue CLI 基本介绍 三、安装Vue CLI 3.1. 安装npm和yarn 3.2. 安装Vue CLI 3.3. 查看 Vue 版本 四、创建启动工程 4.1. 创建项目架子 4.2. 启动工程 五、脚手架目录文件介绍 六、核心文件讲解 6.1. index.html 6.2. main.js 6.3. App.vue 一、…

EtherCAT通信系统中的时钟同步机制

EtherCAT&#xff08;Ethernet for Control Automation Technology&#xff09;通信系统中的时钟同步机制是其核心特性之一&#xff0c;它确保了所有连接的设备能够精确、同步地执行操作。以下是对EtherCAT通信系统中时钟同步机制的详细解释和介绍&#xff1a; 一、分布式时钟…

Linux 进程终止 进程等待

目录 进程终止 退出码 错误码 代码异常终止(信号详解) exit _exit 进程等待 概念 等待的原因 wait 函数原型 参数 返回值 监控脚本 waitpid 概念 函数原型 参数 返回值 WIFEXITED(status) WEXITSTATUS(status) 问题 为什么不用全局变量获得子进程的退出信…

[MySQL]DQL语句(一)

查询语句是数据库操作中最为重要的一系列语法。查询关键字有 select、where、group、having、order by、imit。其中imit是MySQL的方言&#xff0c;只在MySQL适用。 数据库查询又分单表查询和多表查询&#xff0c;这里讲一下单表查询。 基础查询 # 查询指定列 SELECT * FROM …

如何理解ref,toRef,和toRefs

1. ref ref 是 Vue 3 提供的一个用于创建响应式数据的 API。它可以用来创建简单的响应式变量&#xff0c;例如数字、字符串、布尔值或对象等。通过使用ref&#xff0c;当数据发生变化时&#xff0c;相关的组件视图会自动更新。 用法 创建响应式数据&#xff1a; import { ref …

Java 批量导出Word模板生成ZIP文件到浏览器默认下载位置

是不是你们要找的&#xff01;是不是你们要找的&#xff01;是不是你们要找的&#xff01; 先看效果&#xff1a; 1.word模板格式 2.模板位置 3.需要的依赖 <!--POI-TL实现数据导出到word模板--><dependency><groupId>cn.hutool</groupId><artifact…

使用 Nuxt 快速初始化 shadcn-vue 项目

更多 shadcn-vue 中文文档在 Torna Nuxt 安装并配置Nuxt 1. 创建项目 首先&#xff0c;使用 create-nuxt-app 创建一个新的 Nuxt 项目。 如果你选择使用 JavaScript 模板&#xff0c;那么必须存在 jsconfig.json 文件&#xff0c;这样命令行工具&#xff08;CLI&#xff09;…

Flarum:简洁而强大的开源论坛软件

Flarum简介 Flarum是一款开源论坛软件&#xff0c;以其简洁、快速和易用性而闻名。它继承了esoTalk和FluxBB的优良传统&#xff0c;旨在提供一个不复杂、不臃肿的论坛体验。Flarum的核心优势在于&#xff1a; 快速、简单&#xff1a; Flarum使用PHP构建&#xff0c;易于部署&…

CPU用户时间百分比

在计算机系统中&#xff0c;"CPU用户时间百分比&#xff08;CPU User Time&#xff09;"是一个性能监控指标&#xff0c;它描述了CPU在用户模式下执行的累积时间与总的CPU时间的比例。这个指标可以帮助我们了解系统在执行用户态程序时的负载情况。下面是一些关于CPU用…

vue系列==Vuex状态管理器

1、Vuex状态管理器 1、创建一个Vuex的store对象来统一管理多个组件之间共享的状态数据。在创建store对象时&#xff0c;可以配置state、getters、mutations和actions这4个对象&#xff0c;组件之间共享的状态数据在state对象中指定&#xff0c;而基于状态数据的计算属性可以在g…

ubuntu20.04安装ros与rosdep

目录 前置配置 配置apt清华源 配置ros软件源 添加ros安装源&#xff08;中科大软件源&#xff09; 设置秘钥 更新源 ros安装 安装ros 初始化 rosdep 更新 rosdep 设置环境变量 安装 rosinstall 安装验证 启动海龟仿真器 操控海龟仿真器 rosdep安装更新 安装 使用…

C#读取.ini配置文件

INI文件&#xff08;Initialization File&#xff09;是一种简单的文本文件格式&#xff0c;用于存储程序的配置信息。在Visual Studio中&#xff0c;INI文件通常用于存储应用程序或项目的设置和配置数据。这些设置可能包括数据库连接字符串、应用程序参数、用户偏好等。 INI文…

mobile频段要查找、设置并获取相关参数,该怎么破?

今天我们一起来学习查找和设置mobile频段&#xff0c;并获取相关参数。 一、mobile概述 1.1 简介 “4G mobile”指的是第四代移动通信技术&#xff0c;常用于描述通过4G网络进行的高速无线数据传输和通信。4G网络最显著的特征是其高速数据传输能力。理论上&#xff0c;4G可以…

「C/C++」C++11 之<thread>多线程编程

✨博客主页何曾参静谧的博客📌文章专栏「C/C++」C/C++程序设计📚全部专栏「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明目…

CSS元素类型(二)

CSS元素类型 重点 CSS元素类型基本的3种类型&#xff1a;1 块【div]1 可以设置宽度/高度2 如果你不设置宽度的话 宽度父元素3 独占一行【父元素的一行】4 margin【外边框】 auto[自动 将左右二边的空白区域平均分配给元素两端]父元素的居中效果空白区域 父元素宽度 - 本身元…

InsCode线上IDE推荐及使用指南

小编在使用inscode后非常震撼&#xff0c;惊叹于他的线上IDE功能和各类其他功能。 割绳子小游戏,这是小编在inscode上做的游戏部署的网站&#xff0c;大家可以去游玩&#xff0c;有什么值得改进的请大家多多指点。 接下来小编分两期为大家带来inscode线上及线下IDE推荐和使用…

[SAP ABAP] SMW0上传模板

通常来说&#xff0c;一个批量导入的程序必须使用指定的模板&#xff0c;我们需要将模板保存到SAP系统中&#xff0c;以便用户下载并更改。这里我们可以使用事务码SMW0解决上述的问题 1.选择二进制类型 2.输入存放的包 3.创建对象 选择需要进行上传的本地模板文件到SAP系统中 …

LSTM模型改进实现多步预测未来30天销售额

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【BiLSTM模型实现电力数据预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…

中科蓝汛GPIO操作说明

第一种写法&#xff1a; GPIO配置输入模式 //内部上拉 GPIOBDE | BIT(4); //数字IO使能: 0为模拟IO, 1 为数字IO GPIOBDIR | BIT(4); //控制IO的方向: 0为输出, 1为输入. GPIOBFEN & ~BIT(4);//0:当作通用GPIO使用 //1:当作其它功能性IO GPIOBPU | BIT(4); //10K上拉…

docker file容器化部署Jenkins(一)

Jenkins Github地址&#xff1a;https://github.com/jenkinsci/jenkins 国内镜像地址&#xff1a;https://docker.aityp.com/ 准备工作 # 创建持久化卷目录 mkdir /data/jenkins_home/Jenkins拉取镜像 # 由于Jenkins需要JDK&#xff0c;所以直接拉取带有JDK的Jenkins镜像 doc…