Java unterscheidet klar zwischen class
und interface
. (Ich glaube, C # auch, aber ich habe keine Erfahrung damit). Beim Schreiben von C ++ gibt es jedoch keine sprachlich erzwungene Unterscheidung zwischen Klasse und Schnittstelle.
Folglich habe ich die Benutzeroberfläche immer als Problemumgehung für das Fehlen einer Mehrfachvererbung in Java angesehen. Eine solche Unterscheidung ist in C ++ willkürlich und bedeutungslos.
Ich habe mich immer für den Ansatz "Dinge auf die offensichtlichste Weise schreiben" entschieden. Wenn ich also in C ++ eine so genannte Schnittstelle in Java habe, z.
class Foo {
public:
virtual void doStuff() = 0;
~Foo() = 0;
};
und ich entschied dann, dass die meisten Implementierer von Foo
einige gemeinsame Funktionen teilen wollten, die ich wahrscheinlich schreiben würde:
class Foo {
public:
virtual void doStuff() = 0;
~Foo() {}
protected:
// If it needs this to do its thing:
int internalHelperThing(int);
// Or if it doesn't need the this pointer:
static int someOtherHelper(int);
};
Das macht dies dann nicht mehr zu einer Schnittstelle im Java-Sinne.
Stattdessen hat C ++ zwei wichtige Konzepte, die sich auf dasselbe zugrunde liegende Vererbungsproblem beziehen:
virtual
ErbschaftKlassen ohne Mitgliedsvariablen können keinen zusätzlichen Speicherplatz belegen, wenn sie als Basis verwendet werden
"Unterobjekte der Basisklasse können eine Größe von Null haben"
Von denen versuche ich, Nummer 1 zu vermeiden, wo immer dies möglich ist - es kommt selten vor, dass dies wirklich das "sauberste" Design ist. # 2 ist jedoch ein subtiler, aber wichtiger Unterschied zwischen meinem Verständnis des Begriffs "Schnittstelle" und den C ++ - Sprachfunktionen. Infolgedessen bezeichne ich Dinge derzeit (fast) nie als "Schnittstellen" in C ++ und spreche in Bezug auf Basisklassen und deren Größen. Ich würde sagen, dass im Kontext von C ++ "Schnittstelle" eine Fehlbezeichnung ist.
Es ist mir jedoch aufgefallen, dass nicht viele Menschen einen solchen Unterschied machen.
- Kann ich irgendetwas verlieren, indem ich zulasse, dass (z. B.
protected
) Nichtfunktionenvirtual
innerhalb einer "Schnittstelle" in C ++ existieren? (Mein Gefühl ist genau das Gegenteil - ein natürlicherer Ort für gemeinsam genutzten Code) - Ist der Begriff "Schnittstelle" in C ++ sinnvoll - impliziert er nur reine
virtual
oder wäre es fair, C ++ - Klassen ohne Mitgliedsvariablen noch als Schnittstelle zu bezeichnen?
~Foo() {}
in einer abstrakten Klasse ist unter (fast) allen Umständen ein Fehler.
internalHelperThing
in fast allen Fällen simuliert werden.