在枚举标头导致过多的重新编译 [英] enum in header causes excessive recompilations
问题描述
约翰洛科什指的是这个问题,因为的的阴险源
编译时耦合的(图0-3,在他的介绍):
John Lakos refers to this problem as an insidious source of compile-time coupling (Figure 0-3, in his Introduction):
我现在面临的问题是,太多的文件会被编译,因为是在一个枚举物理依赖性。
The problem I am facing is that too many files get compiled because there is a physical dependency on a single enum.
我与枚举定义一个标题:
I have a header with the enum definition:
// version.h
enum Version {
v1 = 1,
v2, v3, v4, v5, ... v100
};
和这由数百个文件。
每个文件定义了一类对象,必须从盘读出的,
使用阅读()
功能。 版
用于确定数据的方式是要被读取
and this is used by hundreds of files.
Each file defines a class of objects, which have to be read from the disk,
using the read()
function. Version
is used to determine the way data is to be read.
一个新的类或类成员介绍每一次,一个新的条目被附加到枚举
Every time a new class or class member is introduced, a new entry is appended to the enum
// 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
}
}
和
// 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);
}
}
现在,你可以看到,一旦对象A
的变化,我们必须引入一个新的条目(例如 V100
)在版本
。因此,所有键入*的.cpp
文件将被编译,即使只阅读()
的对象A
真正需要的 V100
项。
Now, as you can see, once ObjectA
changes, we have to introduce a new entry (say v100
) to the Version
. Consequently all type*.cpp
files will be compiled, even though only read()
of ObjectA
really needs the v100
entry.
我怎样才能反转的枚举的依赖,以最小的改动客户端(即键入*的.cpp
)code,这样只有必要的编译.c文件?
How can I invert the dependency on the enum, with minimal changes to the client (i.e. type*.cpp
) code, so that only the necessary .c files compile ?
下面是一个可能的解决方案,我想到了,但我需要一个更好的:
Here is a possible solution, that I thought of, but I need a better one:
我在想,我可以把在枚举.cpp文件,并揭露 INT
s的各自枚举成员的值:
I was thinking that I could put the enum in a .cpp file, and expose int
s with the values of the respective enum members:
//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.h
typedef const int Version;
和只引进,每次都需要const int的值:
and introduce only the const int values that are needed each time:
// 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
}
}
但我认为这看起来像解决方案非常差,其历史可追溯到pre标头次
but I think this looks like very poor solution, which dates back to pre-header times
推荐答案
我不知道理解你的版本系统。你能不能从阅读解耦对象的定义?
I'm not sure to understand your versioning system. Can't you decouple the objects definitions from the reading?
// 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];
}
然后
// typeB.cpp
#include"ObjectB.h"
// define ObjectB
void ObjectB::setPar ( float mm, float vv, color cc)
{
mass = mm;
velocity = vv;
color = cc;
}
然后在一个(大)文件
then in one (big) file
// 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)
{
...
}
这篇关于在枚举标头导致过多的重新编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!