C ++ allouer de la mémoire pour la liste des objets abstraits de classe

voix
0

Ma compréhension des tableaux C ++ est que vous ne pouvez pas allouer un tableau d'objets abstraits de classe car C ++ ne sait pas comment allouer de la mémoire pour un type de classe encore à déterminer dans les.

Je mets ensemble un petit exemple qui me confond un peu, alors voulu demander un peu plus

#include <iostream>

class Animal {
public:
  virtual void hello() {}
};

class Dog : public Animal {
public:
  void hello() { std::cout << woof! << std::endl; }
};

class Cat : public Animal {
public:
  void hello() { std::cout << meow << std::endl; }
};

int main() {
  Dog d;
  d.hello(); // prints woof!

  Cat c;
  c.hello(); // prints meow

  // how are we allowed to create an array of abstract class?
  // doesn't c++ need to know how to allocate memory for any abstract
  // class in order to do this?
  Animal creatures[5];
  creatures[0] = d;
  creatures[1] = c;
  creatures[4] = d;

  // prints 6Animal
  std::cout << typeid(creatures[0]).name() << std::endl;

  // this appears to call the Animal hello(), which does nothing
  creatures[1].hello();
}

Des questions

  1. Comment est C ++ capable d'allouer de la mémoire pour ce tableau? Pourquoi ne pas se plaindre?
  2. Il semble quelque chose à ce sujet ne manquant pas est en raison de traiter tous les objets que les animaux, à savoir: ne pas faire correctement polymorphisme. Qu'est-ce qui se passe exactement sur, et pourquoi? Est-ce que je viens d'allouer pour une liste de pointeurs pour le faire correctement à la place?

Merci!

Créé 19/03/2020 à 21:55
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
2

Animaln'est pas abstraite. Il ne contient pas de fonctions membres virtuelles pures. Lorsque vous attribuez cet daux éléments de creaturesvous tranchez les.

Si , au contraire, Animal::helloavait été déclarée pure virtuelle, à savoir

class Animal {
public:
  virtual void hello() = 0;
};

Animal creatures[5]ne manquera pas de compiler depuis Animalest maintenant abstraite.


Selon votre deuxième question, le polymorphisme d'exécution en C ++ fonctionne uniquement avec des références et des pointeurs. Si vous êtes familier avec les langages comme Java ou Python , cela peut sembler un peu bizarre au début, mais rappelez - vous que dans ces langues toutes les variables de types de classe sont des pointeurs (ou pointeur comme les choses, en tout cas).

En C ++, Animal creatures[5]sera aménagé dans quelque chose comme mémoire ceci:

creatures
+--------+--------+--------+--------+--------+
| Animal | Animal | Animal | Animal | Animal |
+--------+--------+--------+--------+--------+

En Java, Animal[] creatures = new Animal[5];sera mis en mémoire comme celui - ci:

+-----------+   +---+---+---+---+---+
| creatures +-->+ 0 | 1 | 2 | 3 | 4 |
+-----------+   +-+-+-+-+-+-+-+-+-+-+
                  |   |   |   |   |
       +--------+ |   |   |   |   | +--------+
       | Object +<+   |   |   |   +>+ Object |
       +--------+     |   |   |     +--------+
                      v   |   v
               +------+-+ |  ++-------+
               | Object | |  | Object |
               +--------+ |  +--------+
                          v
                     +----+---+
                     | Object |
                     +--------+

Il n'y a pas d'analogue directe pour les tableaux de C dans des langages comme Java ou Python

Cela signifie que tous les objets dans un tableau C ++ doivent être exactement le type même. Si vous voulez construire quelque chose comme le tableau Java, vous devez utiliser des pointeurs. Vous devez utiliser les standards des classes smart-pointeur std::unique_ptret std::shared_ptr. c'est à dire

std::shared_ptr<Animal> creatures[5];
creatures[0] = std::make_shared<Dog>();
creatures[1] = std::make_shared<Cat>();

creatrues[0]->hello(); // prints "woof!"
creatures[1]->hello(); // prints "meow"
Créé 19/03/2020 à 22:00
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more