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

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(使用前将#替换为@)

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

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 静态与全局

    如果我有一个如下所示的 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