Zugreifen auf geschützte Member in einer abgeleiteten Klasse

Lesezeit: 5 Minuten

Zugreifen auf geschutzte Member in einer abgeleiteten Klasse
mikrofoniert

Ich bin gestern auf einen Fehler gestoßen, und obwohl es einfach ist, ihn zu umgehen, wollte ich sicherstellen, dass ich C++ richtig verstehe.

Ich habe eine Basisklasse mit einem geschützten Mitglied:

class Base
{
  protected:
    int b;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
    }
};

Das kompiliert und funktioniert einwandfrei. Jetzt erweitere ich Base, möchte aber immer noch b verwenden:

class Derived : public Base
{
  protected:
    int d;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
      d=0;
    }
};

Beachten Sie das in diesem Fall DoSomething nimmt immer noch einen Verweis auf a Basenicht Derived. Ich würde erwarten, dass ich noch Zugriff haben kann that.b Innen Derivedaber ich bekomme ein cannot access protected member Fehler (MSVC 8.0 – gcc noch nicht ausprobiert).

Offensichtlich wird ein öffentlicher Getter hinzugefügt b hat das Problem gelöst, aber ich habe mich gefragt, warum ich keinen direkten Zugriff darauf haben konnte b. Ich denke, dass bei Verwendung der öffentlichen Vererbung die geschützten Variablen für die abgeleitete Klasse immer noch sichtbar sind.

  • Kasse gotw.ca/gotw/076.htm (Hinweis: Verwenden Sie dieses Zeug nicht im Produktionscode).

    – Brian

    14. Juli 2010 um 17:32 Uhr

1646970607 888 Zugreifen auf geschutzte Member in einer abgeleiteten Klasse
SLaks

Eine Klasse kann nur auf geschützte Member von Instanzen dieser Klasse oder einer abgeleiteten Klasse zugreifen. Es kann nicht auf geschützte Member von Instanzen einer Elternklasse oder Cousinklasse zugreifen.

In Ihrem Fall die Derived Klasse kann nur auf die zugreifen b geschütztes Mitglied von Derived Instanzen, nicht die von Base Instanzen.

Ändern des Konstruktors, um a zu nehmen Derived Instanz wird das Problem lösen.

  • @AnishaKaul: Sie können nur in einer Instanz Ihres Typs auf die geschützten Member Ihrer Basisklasse zugreifen, nicht in einem Cousin-Typ. Zum Beispiel, Button kann nicht auf eine geschützte Eigenschaft zugreifen Control auf einen TextBox.

    – SLaks

    5. Februar 2012 um 3:07 Uhr

  • You can only access your base class' protected members in an instance of your type, not a cousin type Sie haben wieder die gleiche Aussage geschrieben, die Sie oben geschrieben haben. Schau mal hier:stackoverflow.com/questions/9139824/…

    – Wassermann_Mädchen

    6. Februar 2012 um 3:52 Uhr

  • @SLaks Was meinst du mit “Das Ändern des Konstruktors, um eine abgeleitete Instanz zu verwenden, wird das Problem ebenfalls lösen.” ?

    – Mickael Bergeron Néron

    3. April 2013 um 10:10 Uhr

  • @SLaks, aber warum haben Instanzen der Basisklasse Zugriff auf private Mitglieder anderer Instanzen dieser Basisklasse?

    Benutzer3191398

    3. August 2016 um 16:34 Uhr

  • Wie wäre es mit einer Zugriffsmethode in der Basisklasse, virtuell und geschützt, die Sie von der abgeleiteten Klasse aufrufen können, indem Sie einen Verweis auf eine andere Instanz der Basisklasse oder eine abgeleitete Klasse übergeben?

    – auserdude

    2. Februar 2018 um 12:25 Uhr

protected Mitglieder erreichbar:

  • durch this Zeiger
  • oder zu denselben typgeschützten Membern, auch wenn sie in base deklariert sind
  • oder von Freundesklassen, Funktionen

Um Ihren Fall zu lösen, können Sie eine der letzten beiden Optionen verwenden.

Akzeptieren Sie Derived in Derived::DoSomething oder deklarieren Sie Derived friend zur Basis:

class Derived;

class Base
{
  friend class Derived;
  protected:
    int b;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
    }
};

class Derived : public Base
{
  protected:
    int d;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
      d=0;
    }
};

In einigen Fällen können Sie auch öffentliche Getter in Betracht ziehen.

Wie gesagt, so funktioniert die Sprache.

Eine andere Lösung besteht darin, die Vererbung auszunutzen und an die übergeordnete Methode zu übergeben:

class Derived : public Base
{
  protected:
    int d;
  public:
    void DoSomething(const Base& that)
    {
      Base::DoSomething(that);
      d=0;
    }
};

  • Ich habe in der Frage ein schlechtes Beispiel gegeben, aber ich kann Base::DoSomething nicht aufrufen, da das DoSomething seine Sache tatsächlich anders macht, wenn es in ein Derived und nicht in eine Base kommt.

    – mikrofoniert

    14. Juli 2010 um 15:42 Uhr

Sie haben Zugriff auf die geschützten Mitglieder von Derivedaber nicht die von Base (auch wenn der einzige Grund, warum es ein geschütztes Mitglied von ist Derived ist, weil es von geerbt wird Base)

Zugreifen auf geschutzte Member in einer abgeleiteten Klasse
Martin.Bof

Du kannst es mit versuchen static_cast(pBase)->Base::protected_member

class Base
{
  protected:
    int b;

  public:
    ...
};

class Derived : public Base
{
  protected:
    int d;

  public:
    void DoSomething(const Base& that)
    {
      b += static_cast<const Derived*>(&that)->Base::b;
      d=0;
    }
    void DoSomething(const Base* that)
    {
      b += static_cast<const Derived*>(that)->Base::b;
      d=0;
    }
};

  • Wenn der dynamische Typ von that ist nicht (Lebenslauf) Derived, Das Verhalten ist undefiniert.

    – xskxzr

    15. Februar 2019 um 4:57 Uhr

  • Aber für diesen Fall ist b immer ein Datenmember der Basisklasse!

    – Martin.Bof

    7. März 2019 um 20:52 Uhr

  • Oder besser: b += static_cast(that)->Base::b;

    – Martin.Bof

    7. März 2019 um 21:13 Uhr

1646970608 813 Zugreifen auf geschutzte Member in einer abgeleiteten Klasse
Vishnu Singh

class Derived : public Base
{
  protected:
    int d;
  public:
    void DoSomething()
    {
      b+=this->b;
      d=0;
    }
};

//this will work

  • Wenn der dynamische Typ von that ist nicht (Lebenslauf) Derived, Das Verhalten ist undefiniert.

    – xskxzr

    15. Februar 2019 um 4:57 Uhr

  • Aber für diesen Fall ist b immer ein Datenmember der Basisklasse!

    – Martin.Bof

    7. März 2019 um 20:52 Uhr

  • Oder besser: b += static_cast(that)->Base::b;

    – Martin.Bof

    7. März 2019 um 21:13 Uhr

Zugreifen auf geschutzte Member in einer abgeleiteten Klasse
Stiv Zhops

Nach dem Hack für stl habe ich einen kleinen Code geschrieben, der das Problem des Zugriffs auf die geschützten Member in der abgeleiteten Klasse zu lösen scheint

#include <iostream>

class B
{
protected:
    int a;
public:
    void dosmth()
    {
        a = 4;
    }

    void print() {std::cout<<"a="<<a<<std::endl;}
};

class D: private B
{
public:
    void dosmth(B &b)
    {
        b.*&D::a = 5;
    }
};

int main(int argc, const char * argv[]) {

    B b;
    D d;
    b.dosmth();
    b.print();
    d.dosmth(b);
    b.print();

    return 0;
}

Drucke

a=4
a=5

  • Es stellt sich heraus, dass mein Beispiel fast dasselbe ist wie das oben gepostete. Ich bin auch gewandert, dass es funktioniert. Meiner Meinung nach geht es um das Casting in einen abgeleiteten Typ, aber ich bin mir nicht sicher.

    – Stiv Zhops

    14. Januar 2020 um 16:13 Uhr

989780cookie-checkZugreifen auf geschützte Member in einer abgeleiteten Klasse

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy