Polymorphisme & amp; Pointeurs vers les tableaux [dupliquer]
-
05-07-2019 - |
Question
Cette question a déjà une réponse ici:
J'ai une classe A:
class A
{
public:
virtual double getValue() = 0;
}
Et une classe B:
class B : public A
{
public:
virtual double getValue() { return 0.0; }
}
Et puis dans main () je fais:
A * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //This, or any other index besides 0, causes the program to quit
Si au contraire je le fais:
B * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //Everything else works fine too
Tout se passe bien, mais il semble que mon polymorphisme soit défectueux? Je suis perplexe.
La solution
Vous ne pouvez pas traiter les tableaux de manière polymorphe, aussi, alors que new B [100]
crée un tableau d'objets B
et renvoie un pointeur sur le tableau - ou de manière équivalente le premier élément du tableau - et même s’il est valide d’affecter ce pointeur à un pointeur vers une classe de base, il n’est pas valide de le traiter comme un pointeur dans un tableau d’objets A
.
La principale raison pour laquelle vous ne pouvez pas le faire est que (généralement) les objets dérivés ont une taille différente de celle de leurs classes de base. Par conséquent, toute tentative d'accès au tableau sous la forme d'un tableau d'objets de classe de base n'utilisera pas le bon décalage pour obtenir un pointeur. au prochain sous-objet de la classe de base du prochain membre du tableau de la classe dérivée.
Autres conseils
Il n’ya pas de problème avec le polymrphisme mais avec la façon dont vous traitez avec la mémoire. L'opérateur [] vous fera avancer dans le tableau en indiquant la taille de (A) octets dans le premier cas et la taille de (B) octets dans le deuxième cas. Les objets étant de type B, le * ne pointe pas vers le bon emplacement en mémoire.
Voici une autre façon de voir les choses
char * var;
var = (char*) new B[100];
std::cout << ((A*)var[0]).getValue(); //This works fine
std::cout << ((A*)var[1]).getValue(); //This will fail
std::cout << ((A*)var[sizeof(B)]).getValue(); // should work
Vous n'avez pas alloué les objets du tableau:
for (int i=0;i<100;i++)
var[i] = new B;
(même si je mélange peut-être C ++ et C #)