C ++ Accès membre de classe dérivée de pointeur de classe de base
-
19-09-2019 - |
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?
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
// vous pouvez accéder classe dérivée en utilisant derivedpointer