it-swarm.com.de

Von C++ abgeleitetes Klassenmitglied vom Basisklassenzeiger

Wenn ich ein Objekt der Klasse Derived (mit einer Basisklasse von Base) zuweise und einen Zeiger auf dieses Objekt in einer Variablen speichere, die auf die Basisklasse verweist, wie kann ich auf die Member der Klasse Derived zugreifen?

Hier ist ein Beispiel:

class Base
{
    public:
    int base_int;
};

class Derived : public Base
{
    public:
    int derived_int;
};

Base* basepointer = new Derived();
basepointer-> //Access derived_int here, is it possible? If so, then how?
28
Peter

Nein, Sie können nicht auf derived_int zugreifen, da derived_int zu Derived gehört, während basepointer ein Zeiger auf Base ist.

Sie können es aber auch umgekehrt machen:

Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine

Abgeleitete Klassen erben die Mitglieder der Basisklasse, nicht umgekehrt.

Wenn Ihre basepointer jedoch auf eine Instanz von Derived zeigte, können Sie über eine Besetzung darauf zugreifen:

Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer

Beachten Sie, dass Sie zuerst Ihre Vererbung in public ändern müssen:

class Derived : public Base
49
Peter Alexander

Sie tanzen hier auf dem Minenfeld. Die Basisklasse kann niemals wissen, dass es sich tatsächlich um eine Instanz des abgeleiteten handelt. Am sichersten ist es, eine virtuelle Funktion in die Basis einzuführen:

class Base 
{ 
protected:
 virtual int &GetInt()
 {
  //Die horribly
 }

public: 
 int base_int; 
}; 

class Derived : Base 
{ 
  int &GetInt()
  {
    return derived_int;
  }
public: 
int derived_int 
}; 

basepointer->GetInt() = 0;

Wenn basepointer etwas anderes ist als eine Derived, stirbt Ihr Programm fürchterlich, was das beabsichtigte Ergebnis ist.

Alternativ können Sie dynamic_cast<Derived>(basepointer) verwenden. Dafür benötigen Sie jedoch mindestens eine virtuelle Funktion in der Variablen Base und müssen darauf vorbereitet sein, auf eine Null zu stoßen.

Der static_cast<> ist, wie manche meinen, ein sicherer Weg, um sich in den Fuß zu schießen. Tragen Sie nicht zu den riesigen Horrorgeschichten "Unsicherheit der C-Sprachfamilie" bei.

10
Seva Alekseyev

sie können CRTP verwenden.

sie verwenden grundsätzlich die abgeleitete Klasse in der Vorlage für die Basisklasse

6
kirill_igum

Es ist möglich, die Basisklasse den Typ der abgeleiteten Klasse mitzuteilen. Dies kann erreicht werden, indem aus der Basisklasse eine Vorlage mit einem abgeleiteten Typ erstellt wird. Dieses C++ - Idiom heißt neugierig wiederkehrendes Schablonenmuster .

Wenn Sie die abgeleitete Klasse kennen, kann der Basisklassenzeiger statisch in einen Zeiger auf einen abgeleiteten Typ umgewandelt werden.

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}
4
Paweł Bylica

// wenn Sie wissen, welche abgeleitete Klasse Sie verwenden werden

Abgeleiteter * abgeleiteterPointer = Dynamischer_cast <Abgeleiteter *> Basiszeiger;

// dann können Sie mit derivativepointer auf die abgeleitete Klasse zugreifen

0
Roger Wang