la enumeración en el encabezado provoca recompilaciones excesivas
John Lakos se refiere a este problema comouna fuente insidiosa de acoplamiento en tiempo de compilación (Figura 0-3, en su Introducción):
El problema al que me enfrento es que se compilan demasiados archivos porque hay una dependencia física en una sola enumeración.
Tengo un encabezado con la definición de enumeración:
// version.h
enum Version {
v1 = 1,
v2, v3, v4, v5, ... v100
};
y esto es usado por cientos de archivos. Cada archivo define una clase de objetos, que deben leerse desde el disco, utilizando elread()
función.Version
se utiliza para determinar la forma en que se deben leer los datos.
Cada vez que se introduce una nueva clase o miembro de clase, se agrega una nueva entrada a la enumeración
// 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
}
}
y
// 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);
}
}
Ahora, como puedes ver, una vezObjectA
cambios, tenemos que introducir una nueva entrada (digamosv100
) alVersion
. En consecuencia todostype*.cpp
los archivos serán compilados, aunque soloread()
deObjectA
realmente necesita elv100
entrada.
¿Cómo puedo invertir la dependencia de la enumeración, con cambios mínimos en el cliente (es decir,type*.cpp
) para que solo se compilen los archivos .c necesarios.
Aquí hay una posible solución, que pensé, pero necesito una mejor:
Estaba pensando que podría poner la enumeración en un archivo .cpp y exponerint
s con los valores de los respectivos miembros de enumeración:
//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
hacer un alias para elVersion
escribir de alguna manera
//version.h
typedef const int Version;
e introduzca solo los valores const int que se necesitan cada vez:
// 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
}
}
pero creo que esto parece una solución muy pobre, que se remonta a los tiempos previos al encabezado