2016-07-01 11 views
-1

Nehmen wir an, ich die folgende Anwendungslogik haben:C++ hierarchische Klassenvererbung Design

class classA 
{ 
    classA(ConfigA config) 
}; 

class classB 
{ 
    classB(ConfigB config) 
}; 

class App 
{ 
    void initial(Config config){ 
     if(cond1) 
      new classA(config.getConfigA()); 
     if(cond2) 
      new classB(config.getConfigB()); 
    } 
}; 

Gibt es gutes Muster der Config-Struktur zu entwerfen? Derzeit was ich tue ist

struct BConfig 
{ 
    int a; 
    int b; 
}; 

struct ConfigA:public BConfig 
{ 
    int c; 
}; 
struct ConfigB:public BConfig 
{ 
    int d; 
}; 
struct Config 
{ 
    ConfigA getConfigA(); 
    ConfigB getConfigB(); 
    int a; 
    int b; 
    int c; 
    int d; 
}; 

Ich denke, es gibt einen besseren Weg, es zu tun. Irgendein Vorschlag?

+1

Was sind 'cond1' und' cond2'? Was möchten Sie mit den einmal erstellten Klassen 'classA' und' classB' machen? Lass sie auslaufen klingt nicht wie eine gute Wahl ... – skypjack

+0

Es ist unvollständiger Code. Ich meine, da ist ein Konfigurationszweig. Die Verzweigung kann in ConfigA fortgesetzt werden. – Alfred

+0

Stellen Sie bitte ein [mvce] (http://stackoverflow.com/help/mcve) bereit. – skypjack

Antwort

1

Das klingt wie ein XY-Problem. Sie haben eine bestimmte Lösung, die Sie versuchen zu arbeiten, die möglicherweise die Antwort auf Ihr ursprüngliches Problem ist oder nicht. Auch Ihre Verwendung von new ist im Beispiel unvollständig, es ist unklar, wann oder wie Class Objekte freigegeben werden.

Das heißt, betrachten Schnittstelle Mustern - so etwas wie dies (noch braucht Arbeit, aber es ist ein Anfang):

struct IConfig { 
    // TODO: identification as to which class instance this is. 
    // and/or virtual methods 
    int a; 
    int b; 
    virtual ~IConfig(){} 
}; 

struct ConfigA : public IConfig { 
    int c; 
    virtual ~ConfigA(){} 
}; 

struct ConfigB : public IConfig { 
    int d; 
    virtual ~ConfigB(){} 
}; 

class IClass { 
    // TODO: identification as to which class instance this is. 
    // and/or virtual methods 
    virtual ~IClass(){} 
}; 

class ClassA : public IClass { 
    public: 
    ClassA(const IConfig & iconf) { 
     ConfigA & aconf = dynamic_cast<ConfigA&>(iconf); 
    } 
    virtual ~ClassA(){} 
}; 

class ClassB : public IClass { 
    public: 
    ClassB(const IConfig & iconf) { 
     ConfigB & bconf = dynamic_cast<ConfigB&>(iconf); 
    } 
    virtual ~ClassB(){} 
}; 

class App { 
    IConfig * config; // in case 
    IClass * cls; 
    void initial(IConfig config){ 
     if(cond1) 
     cls = new ClassA(config); 
     else if(cond2) 
     cls = new ClassB(config); 
     else 
     // ... 
    } 
}; 

Nur sicher sein, mit einer solchen Lösung, die cond1 wahr sein IIF die IConfig zu übergeben wird initial ist vom Typ ConfigA, um der Klasse zu entsprechen, die erstellt wird. Sie können weitere Prüfungen hinzufügen, um sicherzustellen, dass dies in der Schnittstelle selbst der Fall ist. Eine virtuelle Methode, die eine Konstante zurückgibt, sollte gut genug sein, aber es hängt wirklich davon ab, was Sie dabei erreichen wollen, da es bereits wie ein unordentlicher Ansatz aussieht.

Eg, vielleicht ein Config lokal für IConfig könnte verwendet werden, um sowohl zu bestimmen - die Klasse zu laden, die wiederum bestimmt, welche Config-Klasse verwendet werden sollen usw.

Nachlese - Sie können in diesem Fall wollen Lassen Sie jede Class haben ihre eigene Implementierung von IConfig, die App (mit IConfig Daten) bestimmen, welche Klasse zu erstellen. Noch einmal, ohne zu wissen, was Sie mit dieser Struktur (im Gegensatz zu anderen) erreichen wollen, kann niemand mit Sicherheit sagen.

+0

Danke. Ihre Lösung ist das Beste, was ich jetzt bekommen kann. Da meine App dynamisch abgeleitete Klassen enthält und verschiedene Klassen unterschiedliche Konfigurationen haben. Die gesamte App-Konfiguration wird in einer einzigen Datei angegeben. Ich habe versucht, ein Entwurfsmuster über die Konfigurationsschnittstelle zu finden, das für diesen Fall geeignet ist. – Alfred