Question

Si j'allouer un objet d'une Derived de classe (avec une classe de base de Base), et stocker un pointeur vers cet objet dans une variable qui pointe vers la classe de base, comment puis-je accéder aux membres de la classe Derived?

Voici un exemple:

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?
Était-ce utile?

La solution

Non, vous ne pouvez pas accéder à derived_int car derived_int fait partie de Derived, tandis que basepointer est un pointeur vers Base.

Vous pouvez le faire l'autre sens que:

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

Les classes dérivées héritent des membres de la classe de base, et non l'inverse.

Cependant, si votre basepointer pointait à une instance de Derived il vous pourriez accéder par un casting:

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

Notez que vous aurez besoin de changer votre héritage à public premier:

class Derived : public Base

Autres conseils

Vous danser sur le champ de mines ici. La classe de base ne peut jamais savoir que c'est en fait une instance de la dérivée. La meilleure façon de le faire serait d'introduire une fonction virtuelle dans la base:

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;

Si les points de basepointer comme autre chose qu'un Derived, votre programme sera horriblement mourir, ce qui est le résultat escompté.

Vous pouvez utiliser dynamic_cast<Derived>(basepointer). Mais vous avez besoin d'au moins une fonction virtuelle dans le Base pour cela, et être prêt à rencontrer un zéro.

Le static_cast<>, comme certains le suggèrent, est un moyen sûr de vous tirer une balle dans le pied. Ne pas contribuer à la grande cache de « unsafety de la famille langage C » histoires d'horreur.

vous pouvez utiliser CRTP

vous utilisez essentiellement la classe dérivée dans le modèle pour la classe de base

Il est possible en laissant la classe de base connaître le type de classe dérivée. Cela peut être fait en faisant la classe de base d'un modèle de type dérivé. Cet idiome C est appelé de curieusement récurrent du motif de matrice.

Connaissant la classe dérivée, le pointeur de classe de base peut être statique-coulé à un pointeur de type dérivé.

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();
}

// si vous savez ce que vous tiriez la classe allez utiliser

* Dérivé derivedpointer = dynamic_cast basepointer;

// vous pouvez accéder classe dérivée en utilisant derivedpointer

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top