2016-11-06 3 views
1

Ich habe eine Zusammenfassung class AbstractClass. Alle meine abgeleiteten Klassen sollten einige const std::vector haben, aber ... dieses Feld ist mit abgeleiteten class (mit Typ) verbunden - nicht mit Instanzen. So könnte es gut sein, es als static zu haben. Natürlich kann ich es nicht in der Basisklasse definieren, und ich kann nicht zwingen, dies in jeder abgeleiteten Klasse zu implementieren, die in der Zukunft hinzugefügt werden kann.Reine virtuelle Methode, die const Reference

Also ich hoffe, dass jemand, der neue abgeleitete Klasse definieren wird, es als static implementieren. (Wenn nicht, sollte das Programm in Ordnung sein, aber es wird eine unnötige Speicherbelegung geben ....). So

Ich habe eine reine vitual Methode zurückkehr diese Variable:

virtual const std::vector<SomeType>& getVec() const = 0; 

Mein existierte abgeleiteten Klasse ist wie folgt definiert:

class DerivedClass : public AbstractClass 
{ 
public: 
    const std::vector<SomeType>& getVec() const { return vec; } 
private: 
    static const std::vector<SomeType> Vec; 
} 

Ich versuche, dies sicher zu tun, und ich denke, über die Möglichkeit, dass andere Programmierer wird neue abgeleitete Klasse hinzufügen und vielleicht auf eine andere Art und Weise implementieren ... Zum Beispiel:

const std::vector<SomeType>& getVec() const { return std::vector<SomeType>{ arg1, arg2}; } 

Ich definierte zurückgegebenen Typ als const reference, weil ich das Kopieren vermeiden möchte (in dem Fall, wenn Vec ist ein Mitglied einer Klasse) ... Ist es ok und sicher für die Öffentlichkeit diese Methode? Gibt es irgendwelche Gefahren bei der Rückkehr const reference?

+6

Das Zurückgeben eines Zeigers/Verweises auf eine Stapelvariable ist ein Fehler. IMO, es hat nichts mit der Gestaltung einer Schnittstelle zu tun. – erenon

+0

Eine Klasse wird verwendet, um a) die Daten und b) den Code, der die Daten verwendet, zusammenzufassen. "Getter" sind ein eindeutiger Beweis für Designfehler ... frage dich selbst "Warum ist der Vektor in diesen abgeleiteten Klassen, und doch ist der Code, der den Vektor verwendet, anderswo? Alternativ frage dich selbst, warum der Code, der diesen Vektor verwendet, nicht mit ist die Daten? –

+0

Siehe auch Martin Fowlers "TellDontAsk" (in diesem Fall erzählen Abgeleitete Klasse ...) –

Antwort

1

Sie können ein Design erzwingen, indem Sie eine andere Schnittstelle zum Erben bereitstellen, wobei das CRTP das gewünschte Verhalten implementiert. Sie möchten, dass jede Ihrer Klassen eine std::vector statische hat? Sie folgendermaßen vorgehen :

class AbstractClass 
{ 
    template<typename> 
    friend class DerivedBase; 

    AbstractClass() = default; 

    public: 
    virtual const std::vector<SomeType>& getVec() const = 0; 
}; 

template<typename CRTP> 
class DerivedBase : AbstractClass 
{ 
    protected: 
    DerivedBase() = default; 
    static const std::vector<SomeType> vec; 

    public: 
    const std::vector<SomeType>& getVec() const { return vec; } 
}; 

class DerivedClass : DerivedBase<DerivedClass> 
{ 
}; 

Jetzt jede DerivedClass ist-ein AbstractClass über einen Vermittler, die diesen Entwurf erzwingt. Und dank des CRTP erhält jeder DerivedClass automatisch seinen eigenen statischen Vektor.


[1] ich wichtige Details im Zusammenhang mit Korrektheit, wie eine virtuelle destructor, ausgelassen den Code kurz zu halten. Vergiss sie nicht.

3

Ist es ok und sicher für die Öffentlichkeit diese Methode?

Ja, es ist.

Gibt es irgendwelche Gefahren bei der Rückkehr const reference?

Nein, gibt es nicht.


Wenn ein anderer Entwickler die Schnittstelle in der Art und Weise implementiert Sie gezeigt haben, werden sie mit undefiniertem Verhalten in ihrem Code am Ende, und früher oder später wird es scheitern.

Es gibt keine Sprachfunktion, die Sie daran hindert, Ihre Schnittstelle zu verwenden und falsch zu implementieren.

0

Wenn Anrufer Ihrer Mitgliedsfunktion nach den Regeln spielen, besteht keine Gefahr, dass diese Funktion public wird.

Eine Möglichkeit, dass sie const_cast den Vektor, und starten Sie die Änderung, existiert auch. Wenn Sie Ihren Benutzern nicht vertrauen, müssen Sie zum Kopieren wechseln.

Verwandte Themen