当前位置:首页 > 科技  > 软件

C++ module编程升级指南,子模块与分区全解析

来源: 责编: 时间:2024-01-02 09:29:00 302观看
导读子模块1.C++ 标准与子模块C++ 标准并没有特别提到子模块,但允许在模块名称中使用点(.),从而可以按任何你想要的层次结构来组织模块。例如,以下是一个 DataModel 命名空间的示例:export module datamodel;import <vector>;ex

子模块

1.C++ 标准与子模块

C++ 标准并没有特别提到子模块,但允许在模块名称中使用点(.),从而可以按任何你想要的层次结构来组织模块。例如,以下是一个 DataModel 命名空间的示例:oY728资讯网——每日最新资讯28at.com

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

Person 和 Address 类都在 DataModel 命名空间内,也在 datamodel 模块中。可以通过定义两个子模块来重构:datamodel.person 和 datamodel.address。oY728资讯网——每日最新资讯28at.com

oY728资讯网——每日最新资讯28at.com

2.子模块的模块接口文件

datamodel.person 子模块的模块接口文件如下:oY728资讯网——每日最新资讯28at.com

export module datamodel.person; // datamodel.person 子模块export namespace DataModel {    class Person { /* ... */ };}

datamodel.address 子模块的模块接口文件如下:oY728资讯网——每日最新资讯28at.com

export module datamodel.address; // datamodel.address 子模块export namespace DataModel {    class Address { /* ... */ };}

最后,定义一个 datamodel 模块如下。它导入并立即导出两个子模块。oY728资讯网——每日最新资讯28at.com

export module datamodel; // datamodel 模块export import datamodel.person; // 导入并导出 person 子模块export import datamodel.address; // 导入并导出 address 子模块import <vector>;export namespace DataModel {    using Persons = std::vector<Person>;}

当然,子模块中类的方法实现也可以放在模块实现文件中。例如,假设 Address 类有一个默认构造函数,仅打印一条语句到标准输出;该实现可以放在一个名为 datamodel.address.cpp 的文件中:oY728资讯网——每日最新资讯28at.com

module datamodel.address; // datamodel.address 子模块import <iostream>;using namespace std;DataModel::Address::Address() {    cout << "Address::Address()" << endl;}

3.使用子模块的好处

用子模块结构化代码的好处是,客户端可以导入他们想要使用的特定部分,或者一次性导入所有内容。例如,如果客户端仅对使用 Address 类感兴趣,以下导入声明就足够了:oY728资讯网——每日最新资讯28at.com

import datamodel.address;

另一方面,如果客户端代码需要访问 datamodel 模块中的所有内容,那么以下导入声明是最简单的:oY728资讯网——每日最新资讯28at.com

import datamodel;

模块分区

1.分区与子模块的区别

分区和子模块之间的区别在于,子模块结构对模块的使用者是可见的,允许用户选择性地只导入他们想使用的子模块。另一方面,分区用于内部结构化模块,对模块的使用者不可见。在模块接口分区文件中声明的所有分区最终必须由主要的模块接口文件导出。一个模块始终只有一个这样的主模块接口文件,即包含 export module 名称声明的接口文件。oY728资讯网——每日最新资讯28at.com

2.创建模块分区

模块分区是通过将模块名称和分区名称用冒号分隔来创建的。分区名称可以是任何合法的标识符。例如,前一节中的 DataModel 模块可以使用分区而不是子模块来重构。以下是 datamodel.person.cppm 模块接口分区文件中的 person 分区:oY728资讯网——每日最新资讯28at.com

export module datamodel:person; // datamodel:person 分区export namespace DataModel {    class Person { /* ... */ };}

3.分区的实现文件注意事项

使用分区时的一个注意事项是:与分区相结合的实现文件只能有一个文件具有特定的分区名称。因此,以下声明开始的实现文件是不正确的:oY728资讯网——每日最新资讯28at.com

module datamodel:address;

相反,你可以将 address 分区的实现放在 datamodel 模块的实现文件中:oY728资讯网——每日最新资讯28at.com

module datamodel; // 不是 datamodel:address!import <iostream>;using namespace std;DataModel::Address::Address() {    cout << "Address::Address()" << endl;}

警告:多个文件不能有相同的分区名称。因此,拥有多个具有相同分区名称的模块接口分区文件是非法的,且分区文件中声明的实现不能放在具有相同分区名称的实现文件中。相反,应该将这些实现放在模块的实现文件中。oY728资讯网——每日最新资讯28at.com

oY728资讯网——每日最新资讯28at.com

4.编写分区模块的要点

编写分区结构的模块时,要记住的重要一点是,每个模块接口分区最终必须由主模块接口文件直接或间接导出。要导入分区,只需指定分区名称,前缀为冒号,例如 import :person。说 import datamodel:person 是非法的。请记住,分区对模块的使用者不可见;分区只在模块内部结构化。因此,用户不能导入特定的分区;他们必须导入整个模块。分区只能在模块内部导入,因此在冒号前指定模块名称是多余的(且非法的)。oY728资讯网——每日最新资讯28at.com

以下是 datamodel 模块的主模块接口文件:oY728资讯网——每日最新资讯28at.com

export module datamodel; // datamodel 模块(主模块接口文件)export import :person;   // 导入并导出 person 分区export import :address;  // 导入并导出 address 分区import <vector>;export namespace DataModel {    using Persons = std::vector<Person>;}

5.使用分区结构化的 datamodel 模块

import datamodel;int main() {    DataModel::Address a;}

注意:分区用于内部结构化模块。分区在模块外部不可见。因此,模块的用户不能导入特定分区;他们必须导入整个模块。早先提到,模块名称声明隐含地包含一个导入名称声明。但对于分区,情况并非如此。例如,datamodel:person 分区没有隐含的 import datamodel 声明。在这个例子中,甚至不允许在 datamodel:person 接口分区文件中添加显式的 import datamodel 声明。这样做会导致循环依赖:datamodel 接口文件包含 import :person 声明,而 datamodel:person 接口分区文件会包含 import datamodel 声明。oY728资讯网——每日最新资讯28at.com

oY728资讯网——每日最新资讯28at.com

实现分区

1.定义和用途

实现分区不需要在模块接口分区文件中声明,它也可以在模块实现分区文件中声明,这是一个带有 .cpp 扩展名的普通源代码文件,在这种情况下,它是一个实现分区,有时也称为内部分区。这种分区不会被主模块接口文件导出。例如,假设你有以下数学主模块接口文件(math.cppm):oY728资讯网——每日最新资讯28at.com

export module math; // math 模块声明export namespace Math {    double superLog(double z, double b);    double lerchZeta(double lambda, double alpha, double s);}

假设进一步数学函数的实现需要一些不能被模块导出的辅助函数。实现分区是放置这些辅助函数的完美位置。以下在名为 math_helpers.cpp 的文件中定义了这样的实现分区:oY728资讯网——每日最新资讯28at.com

module math:details; // math:details 实现分区double someHelperFunction(double a) {    return /* ... */;}

2.实现分区的访问

其他数学模块实现文件可以通过导入这个实现分区来访问这些辅助函数。例如,一个数学模块实现文件(math.cpp)可能看起来像这样:oY728资讯网——每日最新资讯28at.com

module math;import :details;double Math::superLog(double z, double b) {    return /* ... */;}double Math::lerchZeta(double lambda, double alpha, double s) {    return /* ... */;}

当然,使用带有辅助函数的这种实现分区只有在多个其他源文件使用这些辅助函数时才有意义。oY728资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-55042-0.htmlC++ module编程升级指南,子模块与分区全解析

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 我们一起聊聊如何使用Docker来编排Web应用

下一篇: SurfaceView和View的区别,你知道吗?

标签:
  • 热门焦点
  • 一加Ace2 Pro官宣:普及16G内存 引领24G

    一加官方今天继续为本月发布的新机一加Ace2 Pro带来预热,公布了内存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引领,还有呢?#一加Ace2Pro#,2023 年 8 月,敬请期待。”同时
  • 卢伟冰长文解析K60至尊版 对Redmi有着里程碑式的意义

    在今天的Redmi后性能时代战略发布会结束之后,Redmi总经理卢伟冰又带来了一篇长文,详解了为什么 Redmi 要开启后性能时代?为什么选择和 MediaTek、Pixelworks 深度合作?以及后性
  • K60至尊版刚预热 一加Ace2 Pro正面硬刚

    Redmi这边刚如火如荼的宣传了K60 Ultra的各种技术和硬件配置,作为竞品的一加也坐不住了。一加中国区总裁李杰发布了两条微博,表示在自家的一加Ace2上早就已经采用了和PixelWo
  • 7月安卓手机好评榜:三星S23Ultra好评率第一

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年7月1日至7月31日,仅限国内市场。第一名:三星Galaxy S23 Ultra好评率:95.71%在即将迎来新
  • 分布式系统中的CAP理论,面试必问,你理解了嘛?

    对于刚刚接触分布式系统的小伙伴们来说,一提起分布式系统,就感觉高大上,深不可测。而且看了很多书和视频还是一脸懵逼。这篇文章主要使用大白话的方式,带你理解一下分布式系统
  • 慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz&ldquo;难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?&rdquo;这一番话,出自百合网联合创
  • 中国家电海外掘金正当时|出海专题

    作者|吴南南编辑|胡展嘉运营|陈佳慧出品|零态LT(ID:LingTai_LT)2023年,出海市场战况空前,中国创业者在海外纷纷摩拳擦掌,以期能够把中国的商业模式、创业理念、战略打法输出海外,他们依
  • iQOO 11S或7月上市:搭载“鸡血版”骁龙8Gen2 史上最强5G Soc

    去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,iQOO 11不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞屏,同时在快充
  • 最薄的14英寸游戏笔记本电脑 Alienware X14已可以购买

    2022年1月份在国际消费电子展(CES2022)上首次亮相的Alienware新品——Alienware X14现在已经可以购买了,这款笔记本电脑被誉为世界上最薄的 14 英寸游戏笔
Top