2009-05-24 5 views
3

Ich habe eine Klasse mit einem Mitglied m_preferences (ein Vektor, der Assoziation zwischen Wort und Features enthält).Statischer Member und Vererbung

In dieser Klasse ist die m_preferences nicht statisch und daher hat jede Instanz der Klasse ihre spezifische m_preferences.

class Base{ 

private: 

    Preferences m_preferences; 

public: 
... 

} 

Ich habe dann eine abgeleitete Klasse, wo m_preferences statisch werden, weil ich, dass jede neue Instanz dieser Klasse Anteil für Präferenzen, egal was passiert, die gleichen Daten wollte.

class Derived: public Base{ 

private: 

    static Preferences m_preferences; 

public: 
... 

} 

Ich habe einen Verknüpfungsfehler.

Ist es möglich zu tun, was ich tun möchte (Umwandlung eines nicht statischen Mitglieds in ein statisches durch Vererbung)?

Wenn nicht, was ist die Philosophie hinter dieser Unmöglichkeit? War es geplant?

Danke,

Mit freundlichen Grüßen,

Ronan

+2

Was die Objekte? Sieht so aus, als hättest du vielleicht ein Designproblem und du rennst auf den falschen Weg und schlägst an diese Wand. – strager

Antwort

1

Ja, es ist nach Design Sie die Signatur nicht ändern können ein Mitglied während es vererben.

6

Sie können nicht jede Instanz von Base - einschließlich jeder Instanz von Derived - mit einer pro-instance-Elementvariable "Preferences" blockieren, da dies durch die Definition der Base-Klasse garantiert wird.

Was Sie getan haben, ist ein neues statisches Preferences Mitglied der Derived Klasse hinzugefügt, was bedeutet, dass auch als pro-Instanz Preferences Mitglied der Basisklasse zugeordnet Sie auch eine globale Preferences Instanz zwischen allen Derived Instanzen gemeinsam genutzt hast .

Da Sie die gleichen Namen für diese beiden Elemente verwendet haben, im Rahmen einer Parent Elementfunktion, die indentifier mit m_preferences auf die globalen gemeinsame Instanzen beziehen, wenn Sie es wie in Base::m_preferences qualifizieren.

Ihr Link Fehler ist wahrscheinlich, weil Sie eine Definition von Derived::m_preferences in einer Ihrer Übersetzungseinheiten bereitstellen müssen.

z.B. in some.cpp, außerhalb jeder Funktionsrümpfe:

Preferences Derived::m_preferences; 
4

Wenn ich Sie recht gerade lese, wollen Sie eine Hierarchie von Objekten definieren, die entweder eine statische haben wird, oder eine individuelle, Instanzvariable Einstellungen. Versuche dies?

class Base 
{ 
    virtual ~Base(); 
    virtual Preferences& MyPreferences() =0; 
}; 

class DerivedA: public Base 
{ 
public: 
    virtual ~DerivedA(); 
    virtual Preferences& MyPreferences() { return m_preferences; } 

private: 
    Preferences m_preferences; 
}; 

class DerivedB: public Base 
{ 
public: 
    virtual ~DerivedB(); 
    virtual Preferences& MyPreferences() { return preferences; } 

private: 
    static Preferences preferences; 
}; 

Preferences DerivedB::preferences; 

"Transforming", wie Ali Shafai sagte, es auch nicht möglich ist. Das Problem hierbei ist, dass "statische" Elemente Eigenschaften der Klasse selbst sind und nicht einzelne Objekte, während bei virtuellen Deklarationen und Vererbung einzelne Objekte behandelt werden, die nicht der gleichen Klasse angehören, und zwar einheitlich auf einer höheren Abstraktionsebene.

4

Kurze Antwort: Sie verwenden Vererbung nicht ordnungsgemäß.

Lange Antwort: Sie haben Base als einen Typ mit individuellen Einstellungen definiert. Wenn Abgeleitet nicht die Qualifikation "ist-ein" erfüllt (Abgeleitet ist ein Typ, der auch Präferenzen pro Instanz hat), sollte er nicht von Base erben.

Vielleicht ein besseres Design (?):

class NotDerivedAnymore 
{ 

private: 

    static Base m_base; 

public: 
... 

} 
1

Sie sind die is-a Regel der Vererbung zu brechen.

Sie besagt, dass Base ein Typ ist, der sein eigenes Preferences Mitglied hat, und Sie besagt, dass DerivedeinBase ist.

Es scheint, dass Ihre Base und Derived Objekte einige Eigenschaften teilen, aber nicht als direkte Erbe

Ich glaube, das auch das Ergebnis bekommen Sie

class TrueBase{ 
    // Put data and functionality here that really is common for both types. 
    private: 

    virtual Preferences& get_preferences() = 0; 
}; 

class Base : public TrueBase{ 
    private: 

    virtual Preferences& get_preferences() 
    { 
     return m_preferences; 
    } 

    Preferences m_preferences; 
}; 


class Derived: public TrueBase{ 
    private: 

    virtual Preferences& get_preferences() 
    { 
     return m_preferences; 
    } 

    static Preferences m_preferences; 
};