2012-06-06 13 views
15

Ich möchte eine Basisklasse haben, die ein konstantes Feld hat (wie eine eindeutige ID, die der Klasse zugeordnet ist und nach der Kompilierzeit nicht geändert werden kann). Bis jetzt wäre die static const Erklärung in Ordnung. Nun möchte ich diese Basisklasse erben und sicherstellen, dass die Kinder dieser Klasse das gleiche Feld, aber mit ihren eigenen Werten haben. Wie kann ich das machen?Ist es möglich, eine virtuelle statische Konstante in einer C++ - Klasse zu deklarieren?

Lassen Sie uns sagen, ich möchte eine Basisklasse Base mit einem ID Feld mit dem Namen haben, der den int Wert von 0. Dann hält, würde ich A, die Klassen haben, wie B und C, alle von ihnen öffentliche Kinder von Base und ich möchte sicherstellen, dass diese Kinder auch die ID Felder mit den jeweiligen Werten von 1, 2 und 3 haben (durch "sicher", ich meine so etwas wie einen Compiler Fehler zu bekommen, wenn sie nicht ' t habe eine ID explizit deklariert).

Wenn ich dieses Szenario bauen verwalten könnte, würde meine Erwartung, dass für das ID Feld eines Base* Zeiger zu fragen sein, sollte ich unterschiedliche Werte erhalten je nachdem, ob der Zeiger als new A(), new B() oder new C() erstellt wurde.

Meine Schätzung wäre, ID als virtual static const zu deklarieren, was natürlich keinen Sinn ergibt und einen Compilerfehler ergibt.

Aber was kann ich dann tun, um das beschriebene Ergebnis zu erzielen? (Das einzige, was ich mir vorstellen könnte, wäre, ID als eine virtuelle Funktion zu deklarieren, die eine ganze Zahl zurückgibt und den Wert dann in den Funktionskörper festcodiert, aber ich suche nach etwas eleganterem.)

Danke in voraus!

+0

Polymorphismus funktioniert nur für Member-Funktionen und ist für Datenelemente nicht gültig. – Mahesh

+0

Ich habe eine Alternative basierend auf Vorlagen geschrieben: http://stackoverflow.com/a/36797199/1529139 – 56ka

Antwort

15

Eine static Methode kann nicht virtual sein, und keine Datenelemente können virtual sein.

Aber Sie können static Felder in abgeleiteten Klassen ausblenden und verwenden Sie eine virtual Methode, um sie zurückzugeben.

class A 
{ 
public: 
    static const int ID = 0; 
    virtual int getID() { return A::ID; } 
}; 
class B : A 
{ 
public: 
    static const int ID = 1; 
    virtual int getID() { return B::ID; } 
}; 

Alternative:

class A 
{ 
public: 
    A(int id = 0) : ID(id) {} 
    const int ID; 
    getID() { return ID; } 
}; 
class B : public A 
{ 
public: 
    B() : A(1) {} 
}; 
+0

Ja, das ist die einzige Lösung, die ich bisher kannte. Aber gibt es keine Möglichkeit, dies eleganter/einfacher zu lösen? Oder wenn dies der einzige Weg ist, dann ist meine Frage eher: Aus welchem ​​Grund funktioniert die virtuelle Vererbung, die mit Funktionen arbeitet, nicht mit Datenmitgliedern? Ich verstehe, warum eigentlich 'static virtual' keinen Sinn macht, aber ich kann nicht wirklich verstehen, warum, sagen wir, ein einfaches' virtual const int'-Feld keinen Sinn ergibt ... –

+0

@ SiskaÁdám weil polymorphes Verhalten nicht ist für Datenelemente definiert. So ist die Sprache gestaltet. Und es ist eine gute Sache, IMO. –

+0

@ SiskaÁdám Ich habe eine Alternative veröffentlicht, aber ich finde immer noch die erste besser. –