enum im Header führt zu übermäßigen Neukompilierungen

John Lakos bezeichnet dieses Problem alseine heimtückische Quelle für die Kopplung zur Kompilierungszeit (Abbildung 0-3 in seiner Einführung):

Das Problem besteht darin, dass zu viele Dateien kompiliert werden, da eine physische Abhängigkeit von einer einzelnen Aufzählung besteht.

Ich habe einen Header mit der Enum-Definition:

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

und dies wird von Hunderten von Dateien verwendet. Jede Datei definiert eine Klasse von Objekten, die mit dem @ von der Festplatte gelesen werden müsseread() Funktion.Versionit @ wird festgelegt, wie Daten gelesen werden sollen.

Jedes Mal, wenn eine neue Klasse oder ein neues Klassenmitglied vorgestellt wird, wird ein neuer Eintrag an die Aufzählung @ angehäng

// 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
    }
}

un

// 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);
    }
}

Nun, wie Sie sehen können, einmalObjectA Änderungen, müssen wir einen neuen Eintrag einführen (sagen Siev100) zumVersion. Folglich alletype*.cpp -Dateien werden kompiliert, obwohl nurread() vonObjectA braucht wirklich dasv100 entry.

Wie kann ich die Abhängigkeit von der Aufzählung mit minimalen Änderungen am Client umkehren (d. H.type*.cpp) Code, damit nur die benötigten .c-Dateien kompiliert werden?

Hier ist eine mögliche Lösung, die ich mir überlegt habe, aber ich brauche eine bessere:

Ich dachte, ich könnte die Aufzählung in eine CPP-Datei einfügen undints mit den Werten der jeweiligen Enum-Mitglieder:

//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

mache einen Alias für dasVersion Typ irgendwie

//version.h
typedef const int Version;

und geben Sie nur die konstanten int-Werte ein, die jedes Mal benötigt werden:

// 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
    }
}

Aber ich denke, das sieht nach einer sehr schlechten Lösung aus, die aus der Zeit vor dem Header stammt.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage