C++ && protected

Enumerator

Mitglied Kamel
Hi!

Als "alter" C-Coder raufe ich mir mal wieder die Haare am OO-Konzept. Vielleicht kann mir einer von Euch mal erklären, warum ich folgende Fehlermeldung...
Code:
test.cpp: In constructor ‘beta::beta(alpha&)’:
test.cpp:10: error: ‘void* alpha::m_ptr’ is protected
test.cpp:18: error: within this context
... erhalte wenn ich diesen Schnippel hier...
C++:
#include <cstring>

class alpha
{
public:
    alpha(void *p = NULL):
      m_ptr(p)
    {};
protected:
    void *m_ptr;
};

class beta
: public alpha
{
public:
    beta(alpha &a):
      alpha(a.m_ptr)
    {};
};

int
main(void)
{
    alpha a(NULL);
    alpha b(a);
    return 0;
}
... übersetzen will?! protected bedeutet doch immer noch, dass ich von abgeleiteten Klassen darauf zugreifen kann, oder etwa nicht?

Gruß
Enum
 
Hi.

Ja, protected bedeutet das man in abgeleiteten Klassen drauf zugreifen kann. Allerdings darf man nicht direkt auf die nicht-statische Member eines alpha zugreifen, sondern nur über einen Zeiger oder Referenz auf eine abgeleitete Klasse.

D.h. du könntest auf this->m_ptr (wobei this == beta*) zugreifen (obwohl dieses Attribut von alpha geerbt wurde).

C++:
beta::beta(alpha& a, beta& b) 
: alpha(a.m_ptr), // Fehler
  beta(b.m_ptr) // OK.
{}
Gruß
 
Danke für die Aufklärung!

Wenn ich also einer abgeleiteten Klasse erlauben will direkt auf einen "protected" Member der Basis (aber einer anderen Instanz) zuzugreifen, bin ich gezwungen einen "protected static getter" zu schreiben?!
C++:
#include <cstring>

class alpha
{
public:
    alpha(void *p = NULL):
      m_ptr(p)
    {};
protected:
    static void *get_ptr(alpha&);
    void *m_ptr;
};

void*
alpha::get_ptr(alpha &a)
{
    return a.m_ptr;
}

class beta
: public alpha
{
public:
    beta(alpha &a):
      alpha(get_ptr(a))
    {};
};

int
main(void)
{
    alpha a(NULL);
    alpha b(a);
    return 0;
}
Kommt mir das nur so vor oder ist das wirklich dämlich?

Gruß
Enum
 
Wenn ich also einer abgeleiteten Klasse erlauben will direkt auf einen "protected" Member der Basis (aber einer anderen Instanz) zuzugreifen, bin ich gezwungen einen "protected static getter" zu schreiben?!
Du könntest es auch so machen:
C++:
beta::beta(alpha& a) 
  : alpha(a)
{}
Die protected Regelung schützt die Daten der Basisklasse vor externem Zugriff.

C++ bietet ja einige Möglichkeiten den Zugriff zu regeln. Du könntest auch friend's deklarieren.

Es wäre evtl. auch notwendig nochmal über die Notwendigkeit der Klassenhierarchie als solche nachzudenken.
Du meintest wohl
C++:
beta b(a);
Oder?!

Gruß
 
Ja, das b sollte ein beta sein...
Dennoch, ein beta muss in der lage sein auf m_ptr eines alpha zuzugreifen. Da Das oben nur ein Beispiel ist und ich eigentlich gerade einen Wrapper für die API um ein C-Struct schreibe, komme ich eh' nicht darum einen Operator zur "Abwärtskompatibilität" mit C zu definieren und damit das Konzept von protected Membern komplett auszuhebeln... Wenigstens kann ich den Operator auch anstelle des statischen Accessors verwenden.

Gruß
 
Dennoch, ein beta muss in der lage sein auf m_ptr eines alpha zuzugreifen.
Dann müßtest du m_ptr public machen oder beta (bzw. Methoden von beta) als friend deklarieren.

protected bedeutet nunmal, dass man auf *eigene* vererbte Attribute/Methoden zugreifen kann, aber nicht auf die anderer Objekte.
Da Das oben nur ein Beispiel ist und ich eigentlich gerade einen Wrapper für die API um ein C-Struct schreibe, komme ich eh' nicht darum einen Operator zur "Abwärtskompatibilität" mit C zu definieren und damit das Konzept von protected Membern komplett auszuhebeln... Wenigstens kann ich den Operator auch anstelle des statischen Accessors verwenden.
Ja, das Beispiel ist wirklich etwas an den Haaren herbeigezogen. Da du in alpha Besitz von einem Zeiger ergreifst müßtest du sowieso die großen Drei implementieren und, da du vererbst müßtest du zumindest den Destruktor virtuell machen usw.

Gruß
 
Zurück