C ++ asignación de memoria para la lista de objetos de la clase abstracta

votos
0

Mi comprensión de arrays de C ++ es que no se puede asignar una matriz de objetos clase abstracta ya que C ++ no sabe cómo asignar memoria para un tipo de clase todavía-a-ser-decidido.

Monté un pequeño ejemplo que me confunde un poco, por lo que quería hacer un poco más

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

preguntas

  1. ¿Cómo es C ++ capaz de asignar memoria para esta matriz? ¿Por qué no se quejan?
  2. Parece algo acerca de esto no se debe a no tratar a todos los objetos como animales, es decir: no hacer correctamente polimorfismo. ¿Qué es exactamente que está pasando, y por qué? No sólo tengo que asignar a una lista de punteros para hacer esto correctamente en su lugar?

¡Gracias!

Publicado el 19/03/2020 a las 21:55
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
2

Animalno es abstracto. No contiene funciones miembro virtuales puras. Cuando se asigna cy dde los elementos de creaturesque está rebanando ellos.

Si por el contrario, Animal::hellohabía sido declarado puro virtual, es decir,

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

Animal creatures[5]sería dejar de compilar desde Animalahora es abstracta.


De acuerdo con la segunda pregunta, el polimorfismo en tiempo de ejecución en C ++ sólo funciona con referencias y punteros. Si está familiarizado con lenguajes como Java o Python esto puede parecer un poco extraño al principio, pero recuerda que en esos idiomas todas las variables de los tipos de clases son punteros (o puntero que las cosas, de todos modos).

En C ++, Animal creatures[5]será expuesto en la memoria algo como esto:

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

En Java, Animal[] creatures = new Animal[5];será expuesto en la memoria de esta manera:

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

No hay ninguna analógica directa para las matrices C ++ en lenguajes como Java o Python

Eso significa que todos los objetos en un C ++ matriz debe ser exactamente el mismo tipo. Si usted quiere construir algo así como la matriz de Java, debe utilizar punteros. Debe utilizar las clases-puntero inteligente estándar std::unique_ptry std::shared_ptr. es decir

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"
Respondida el 19/03/2020 a las 22:00
fuente por usuario

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