enum в заголовке вызывает чрезмерную перекомпиляцию

Джон Лакос называет эту проблемуковарный источник связи во время компиляции (Рисунок 0-3, в его введении):

Проблема, с которой я сталкиваюсь, заключается в том, что слишком много файлов компилируется, потому что существует физическая зависимость от одного перечисления.

У меня есть заголовок с определением перечисления:

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

и это используется сотнями файлов. Каждый файл определяет класс объектов, которые должны быть прочитаны с диска, используяread() функция.Version используется для определения способа чтения данных.

Каждый раз, когда вводится новый класс или член класса, новая запись добавляется в 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);
    }
}

Теперь, как вы можете видеть, однаждыObjectA изменения, мы должны ввести новую запись (скажем,v100) кVersion, Следовательно, всеtype*.cpp файлы будут скомпилированы, хотя толькоread() изObjectA действительно нужноv100 запись.

Как я могу инвертировать зависимость от перечисления, с минимальными изменениями для клиента (т.е.type*.cpp), чтобы компилировались только необходимые .c файлы?

Вот возможное решение, о котором я подумал, но мне нужно лучшее:

Я думал, что могу поместить enum в файл .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
    }
}

но я думаю, что это выглядит как очень плохое решение, которое восходит ко времени перед заголовком

Ответы на вопрос(2)

Ваш ответ на вопрос