标头中的枚举会导致过多的重新编译

2023-12-06

约翰·拉科斯 (John Lakos) 将这个问题称为一个阴险的来源 编译时耦合(图0-3,在他的简介中):

我面临的问题是编译了太多文件,因为对单个枚举存在物理依赖性。

我有一个带有枚举定义的标题:

// version.h
enum Version {
    v1 = 1,
    v2, v3, v4, v5, ... v100
};

这被数百个文件使用。 每个文件定义一类对象,必须从磁盘读取这些对象, 使用read()功能。Version用于确定读取数据的方式。

每次引入新的类或类成员时,都会将新条目附加到枚举中

// typeA.cpp
#include "version.h"

void read (FILE *f, ObjectA *p, Version v) 
{
    read_float(f, &p->x);
    read_float(f, &p->y);
    if (v >= v100) { 
        read_float(f, &p->z);  // after v100 ObjectA becomes a 3D
    }
}

and

// typeB.cpp
#include "version.h"

void read (FILE *f, ObjectB *p, Version v)
{
    read_float (f, &p->mass);
    if (v >= v30) {
        read_float (f, &p->velocity);
    }
    if (v >= v50) {
        read_color (f, &p->color);
    }
}

现在,正如你所看到的,一旦ObjectA更改,我们必须引入一个新条目(例如v100)到Version。因此所有type*.cpp文件将被编译,即使只有read() of ObjectA确实需要v100 entry.

如何反转对枚举的依赖,并对客户端进行最小的更改(即type*.cpp)代码,以便仅编译必要的 .c 文件?

这是我想到的一种可能的解决方案,但我需要一个更好的解决方案:

我想我可以将枚举放入 .cpp 文件中,然后公开ints 与各个枚举成员的值:

//version.cpp
enum eVersion {
    ev1 = 1,
    ev2, ev3, ev4, ev5, ... ev100
};

const int v1 = ev1;
const int v2 = ev2;
....
const int v100 = ev100;   // introduce a new global int for every new entry in the enum

Version以某种方式输入

//version.h
typedef const int Version;

并只引入每次需要的 const int 值:

// typeA.cpp
#include "version.h"

extern Version v100;    ///// *** will be resolved at link time

void read (FILE *f, ObjectA *p, Version v) 
{
    read_float(f, &p->x);
    read_float(f, &p->y);
    if (v >= v100) { 
        read_float(f, &p->z);  // after v100 ObjectA becomes a 3D
    }
}

但我认为这看起来是一个非常糟糕的解决方案,可以追溯到标题前的时间


我不确定是否了解您的版本控制系统。你不能将对象定义与读取分离吗?

// ObjectA.cpp

#include"ObjectA.h"  

// define ObjectA

void ObjectA::setPar ( float xx, float yy, float zz) 
{
    x = v[0];
    y = v[1];
    z = v[2]; 
}

then

// typeB.cpp

#include"ObjectB.h"  

// define ObjectB

void ObjectB::setPar ( float mm, float vv, color cc) 
{
    mass = mm;
    velocity = vv;
    color = cc; 
}

然后在一个(大)文件中

// readObject.cpp

#include"version.h"
#include"ObjectA.h"
#include"ObjectB.h"

void read (FILE *f, ObjectA *p, Version v) 
{
    float x,y,z;
    read_float(f, x);
    read_float(f, y);
    if (v >= v100) { 
        read_float(f, z);  // after v100 ObjectA becomes a 3D
    } else z=0.0;          // whatever
    p->setPar(x,y,z);
}

void read (FILE *f, ObjectB *p, Version v)
{
    ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

标头中的枚举会导致过多的重新编译 的相关文章

  • 部署 MVC4 项目时出错:找不到文件或程序集

    过去 我只需使用 Visual Studio 2012 发布到 AWS 菜单项即可部署我的 MVC4 网站 到 AWS Elastic Beanstalk 现在 程序可以在本地编译并运行 但无法部署 从消息来看 它似乎正在寻找不在当前部署的
  • 创建 DirectoryEntry 实例以供测试使用

    我正在尝试创建 DirectoryEntry 的实例 以便可以使用它来测试将传递 DirectoryEntry 的一些代码 然而 尽管进行了很多尝试 我还是找不到实例化 DE 并初始化它的 PropertyCollection 的方法 我有
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 静态与全局

    如果我有一个如下所示的 C 文件 那么它们之间有什么区别i and j include
  • 在 url('data:image/svg+xml') 中使用 CSS 变量

    我使用以下方法在 div 周围实现虚线边框 div width 100px height 100px border radius 16px background image url data image svg xml 3csvg stro
  • 如何将图例绘制到绘图画布外的多列中?

    I 有一个数据文件它由 131 列和 4 行组成 我将其绘制成 python 如下 df pd read csv data csv df plot figsize 15 10 一旦绘制完成 所有 131 个传说就会像一座巨大的塔楼一样聚集在
  • 卡夫卡|增加多个主题的复制因子

    我有一个 3 代理 Kafka 集群 其中有许多主题 复制因子为 1 我知道我可以通过将带有分区重新分配配置的 JSON 文件传递 给kafka reassign partitions sh 我的困惑是 我应该传递一个包含所有主题的分区重新
  • 两个数相除[重复]

    这个问题在这里已经有答案了 我正在用 C 进行一些自学 虽然我做了比这更复杂的项目 但我无法弄清楚问题是什么 private void button4 Click object sender EventArgs e int headcoun
  • 在 Javafx Tableview 中选择行

    根据我上面的表格视图 一旦我单击任何操作图标 它将导航到另一个窗口 包含选定的数据 当再次返回到此表视图时 我如何保持选择同一行 谢谢 很抱歉实际上我已经复制了question 正确答案就在那里 Platform runLater new
  • Observable.combineLatest 不是一个函数

    我有一个Home页面 用户点击其中的某个位置联络我被重定向到Contact page home component html div a Contact me a div home component ts import Component
  • 用Java复制和移动文件,不同方法的解释和比较

    我实现了一个文件操作功能 并且我注意到 Java 提供了多种复制和移动文件的技术 您可以在下面找到代码片段 简要描述这些方法 方法 1 File from new File src getPath File to new File dst
  • swift 编译器显示预期声明错误? [复制]

    这个问题在这里已经有答案了 当这段代码被写成AllListViewController并运行 编译器显示预期声明错误 for list in lists let item ChecklistItems item text Item for
  • ROCm 和 CUDA GPU 在一种型号上?

    我想在多个 GPU 上编译模型 是否可以在同一型号上将带有 ROCm 的 AMD GPU 与 Nvidia CUDA GPU 一起使用 我想这是不可能的 因为您需要安装特殊版本的tensorflow才能启用ROCm tensorflow N
  • 列名称或提供的值的数量与表定义不匹配 - 无法识别根本原因

    出现错误 cmd ExecuteNonQuery 我当前的代码 Using con As New SqlConnection sConString Using cmd As New SqlCommand INSERT INTO MC Ent
  • 找不到参数编组器的隐式值:spray.httpx.marshalling.ToResponseMarshaller

    我在用着 val akkaV 2 2 3 val sprayV 1 2 0 Seq io spray spray can sprayV io spray spray routing sprayV io spray spray json 1
  • 泛型结构的构造函数中出现“预期类型参数”错误

    我正在尝试将活塞纹理存储在结构中 struct TextureFactory
  • HXT:以纯代码读取 HTML 并将其写入字符串时的令人惊讶的行为

    我想从字符串中读取 HTML 对其进行处理并使用 HXT 将更改后的文档作为字符串返回 由于此操作不需要 IO 我宁愿执行箭头runLA比与runX 代码如下所示 为了简单起见 省略了处理 runLA hread gt gt gt writ
  • Elasticsearch 聚合结果分页

    我想使用 Elasticsearch 聚合查询的 size 和 from 属性进行分页 这可能吗 目前我只知道 size 属性 0 以获得无限结果 聚合分页功能尚未实现 您可以使用尺寸组合并排除构面中的特征
  • 将 RegEx 从 JavaScript 转换为 Java

    好的 所以我尝试用不在 或 内的 分割字符串 我有一个适用于 JavaScript 的正则表达式 但无法将其转换为 Java 语法 JS 正则表达式 g 例句 ex1 ex2 ex3 ex 4 ex 4 ex ex 当我尝试在 Java 中
  • .htaccess 301 重定向不起作用?

    我的根目录中有一个 page1 html 形式的静态页面 根目录中还有另一个页面 index php 我想做的是将所有旧的传入链接移动到指向 WordPress 目录 我通过 htaccess 和 index php 获得了要重定向的主域
  • PHP中如何将数字转换为字母?

    这个函数 numtoalpha 如何打印出大于 9 的值的字母等效项 结果是这样的 A 10 B 11 等等 PHP net 甚至没有该功能 或者我没有在正确的位置查找 但我确信它说的是功能
  • 限制每日访问

    我想在我的网站中实现一项限制对特定页面的访问的功能 每个 IP 每天应允许 2 次访问 我正在考虑创建一个 mysql 表并写入 ip ip 访问该网站的时间 然后创建一个 cron 作业 每 24 小时删除所有条目 但我担心他可能会导致服
  • 标头中的枚举会导致过多的重新编译

    约翰 拉科斯 John Lakos 将这个问题称为一个阴险的来源 编译时耦合 图0 3 在他的简介中 我面临的问题是编译了太多文件 因为对单个枚举存在物理依赖性 我有一个带有枚举定义的标题 version h enum Version v1