371 Stimmen

Was ist der Unterschied zwischen privaten und geschützten Mitgliedern von C++-Klassen?

Was ist der Unterschied zwischen private y protected Mitglieder in C++-Klassen?

Aus den Best-Practice-Konventionen weiß ich, dass Variablen und Funktionen, die nicht außerhalb der Klasse aufgerufen werden, zu private -aber wenn ich mir mein MFC-Projekt ansehe, scheint MFC zu bevorzugen protected .

Was ist der Unterschied und welche sollte ich verwenden?

0 Stimmen

Wenn Sie eine Bibliothek entwerfen, ist jedes geschützte (und nicht private) Mitglied eine Belastung. Wenn Sie bei internen Klassen alles, was nicht öffentlich ist, geschützt machen, sparen Sie Zeit und müssen weniger Klassen überarbeiten, um ein Mitglied von privat in geschützt zu ändern.

477voto

Firas Assaad Punkte 23800

Private Mitglieder sind nur innerhalb der Klasse, die sie definiert, zugänglich.

Geschützte Mitglieder sind in der Klasse, die sie definiert, und in Klassen, die von dieser Klasse erben, zugänglich.

Edit: Beide sind auch für Freunde ihrer Klasse zugänglich, und im Falle von geschützten Mitgliedern auch für Freunde ihrer abgeleiteten Klassen.

Edit 2: Verwenden Sie das, was im Zusammenhang mit Ihrem Problem sinnvoll ist. Du solltest versuchen, Mitglieder wann immer möglich privat zu machen, um die Kopplung zu reduzieren und die Implementierung der Basisklasse zu schützen, aber wenn das nicht möglich ist, dann verwende geschützte Mitglieder. Prüfen Sie C++ FAQ für ein besseres Verständnis des Themas. Diese Frage zu geschützten Variablen könnte auch helfen.

13 Stimmen

Der Link zu C++ FAQ Lite wurde verschoben nach isocpp.org/wiki/faq/grundlagen-der-vererbung

161voto

paercebal Punkte 78198

Öffentlich Mitglieder einer Klasse A sind für alle und jeden zugänglich.

Geschützt Mitglieder einer Klasse A sind außerhalb des Codes von A nicht zugänglich, aber sie sind vom Code jeder von A abgeleiteten Klasse zugänglich.

Privat Mitglieder einer Klasse A sind nicht außerhalb des Codes von A oder aus dem Code einer von A abgeleiteten Klasse zugänglich.

Die Entscheidung zwischen geschützt oder privat ist also letztlich eine Antwort auf die folgenden Fragen: Wie viel Vertrauen sind Sie bereit, in den Programmierer der abgeleiteten Klasse zu setzen?

Standardmäßig anzunehmen, dass der abgeleiteten Klasse nicht zu trauen ist, und machen Sie Ihre Mitglieder privat . Wenn Sie einen sehr guten Grund haben, den abgeleiteten Klassen freien Zugang zu den Interna der Mutterklasse zu gewähren, können Sie diese schützen.

0 Stimmen

Die abgeleitete Klasse sollte ein Typ Ihrer Klasse sein, und die geschützten Daten der Basisklasse sind Teil der Daten der abgeleiteten Klasse. Vom Autor der abgeleiteten Klasse wird erwartet, dass er mit diesen Daten richtig umgeht, sonst handelt es sich um einen Fehler. Private Daten in einer Basisklasse sind jedoch etwas, das der Autor der abgeleiteten Klasse nicht kontrollieren kann.

0 Stimmen

@CashCow the protected data of the base class is part of the data of the derived class. In der Tat. Ist es dann nicht besser, wenn der Autor der abgeleiteten Klasse diese Daten in seiner Klasse deklariert, statt in meiner?... :-) ... The writer of the derived class is expected to handle this data properly or it is a bug. Beim NVI-Muster besteht das Ziel darin, alles privat zu machen, einschließlich der Methoden, um den Schaden zu begrenzen, den der Autor der abgeleiteten Klasse in der Hierarchie anrichten könnte. Geschützte Methoden sind bereits ein potenzielles Problem. Ich bin nicht davon überzeugt, dass es der richtige Ansatz ist, dieses Problem durch die Verwendung geschützter Zustände noch zu verschärfen.

0 Stimmen

Es könnte sein, was erfordern würde, dass Sie virtuelle "Getter" in der Basisklasse haben, um darauf zuzugreifen. Und obwohl man Zwischenklassen haben kann, um die verschiedenen Arten der Implementierung des Datenmusters zu realisieren, ist es nicht immer praktisch, dies zu tun. Ein "Muster", das in Sprachen ohne "const"-Modifikator üblich, in C++ jedoch meist nicht notwendig ist, besteht beispielsweise darin, eine schreibgeschützte Basisklasse und schreibbare abgeleitete Klassen zu haben. In C++ kann dies auch einfach deshalb sinnvoll sein, weil man mehr als eine Möglichkeit zum Laden (Initialisieren) der Daten haben möchte.

81voto

Roddy Punkte 64661

Auf geschützte Mitglieder kann von abgeleiteten Klassen aus zugegriffen werden. Auf private nicht.

class Base {

private: 
  int MyPrivateInt;
protected: 
  int MyProtectedInt;
public:
  int MyPublicInt;
};

class Derived : Base
{
public:
  int foo1()  { return MyPrivateInt;} // Won't compile!
  int foo2()  { return MyProtectedInt;} // OK  
  int foo3()  { return MyPublicInt;} // OK
};

class Unrelated 
{
private:
  Base B;
public:
  int foo1()  { return B.MyPrivateInt;} // Won't compile!
  int foo2()  { return B.MyProtectedInt;} // Won't compile
  int foo3()  { return B.MyPublicInt;} // OK
};

Was die "beste Praxis" betrifft, so kommt es darauf an. Wenn auch nur die geringste Möglichkeit besteht, dass jemand eine neue Klasse von Ihrer bestehenden Klasse ableiten möchte und Zugriff auf die internen Mitglieder benötigt, sollten Sie sie geschützt und nicht privat machen. Wenn sie privat sind, kann es schwierig werden, von Ihrer Klasse zu erben.

5 Stimmen

Ich bin anderer Meinung: Wenn es eine schwache Möglichkeit gibt, dass keine Unterklasse benötigen wird, machen Sie es privat. Es sei denn, Sie beabsichtigen um Ihre Klasse unterzuordnen, verwenden Sie das Schablonenmethodenmuster.

0 Stimmen

Wenn Sie nicht beabsichtigen, Ihre Klasse als Unterklasse zu verwenden, machen Sie sie endgültig. Private vs. Protected ist nur ein Thema, wenn die Klasse unterklassifiziert werden soll.

27voto

Toon Krijthe Punkte 51819

Der Grund, warum MFC geschützt ist, liegt darin, dass es ein Framework ist. Wahrscheinlich möchten Sie die MFC-Klassen subklassifizieren, und in diesem Fall ist eine geschützte Schnittstelle erforderlich, um auf Methoden zuzugreifen, die für die allgemeine Verwendung der Klasse nicht sichtbar sind.

10voto

Mats Fredriksson Punkte 19007

Es hängt alles davon ab, was Sie tun wollen und was die abgeleiteten Klassen sehen können sollen.

class A
{
private:
    int _privInt = 0;
    int privFunc(){return 0;}
    virtual int privVirtFunc(){return 0;}
protected:
    int _protInt = 0;
    int protFunc(){return 0;}
public:
    int _publInt = 0;
    int publFunc()
    {
         return privVirtFunc();
    }
};

class B : public A
{
private:
    virtual int privVirtFunc(){return 1;}
public:
    void func()
    {
        _privInt = 1; // wont work
        _protInt = 1; // will work
        _publInt = 1; // will work
        privFunc(); // wont work
        privVirtFunc(); // will work, simply calls the derived version.
        protFunc(); // will work
        publFunc(); // will return 1 since it's overridden in this class
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X