C ++ l'allocazione della memoria per la lista di oggetti classe astratta

voti
0

La mia comprensione di array C ++ è che non è possibile allocare un array di oggetti classe astratta dal C ++ non sa come allocare memoria per un tipo di classe ancora-a-essere-deciso.

Ho messo insieme un piccolo esempio che mi confonde un po ', in modo voluto chiedere un po' di più

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

Domande

  1. Come è C ++ in grado di allocare memoria per questo array? Perché non si lamentano?
  2. Sembra qualcosa su questo non mancando è dovuto al trattamento di tutti gli oggetti come animali, vale a dire: non adeguatamente facendo polimorfismo. Che cosa esattamente sta succedendo, e perché? Non mi resta che destinare per un elenco di puntatori a farlo correttamente, invece?

Grazie!

È pubblicato 19/03/2020 alle 21:55
fonte dall'utente
In altre lingue...                            


1 risposte

voti
2

Animalnon è astratta. Non contiene funzioni membro virtuali puri. Quando si assegna ce dagli elementi di creaturesche si sta affettare loro.

Se invece, Animal::helloera stato dichiarato puro-virtuale, vale a dire

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

Animal creatures[5]sarebbe riuscire a compilare in quanto Animalè ora astratta.


Come per la seconda domanda, il polimorfismo runtime in C ++ funziona solo con riferimenti e puntatori. Se si ha familiarità con linguaggi come Java o Python questo può sembrare un po 'strano in un primo momento, ma ricorda che in quelle lingue tutte le variabili di tipi di classe sono puntatori (o puntatore-come le cose, comunque).

In C ++, Animal creatures[5]saranno disposti in qualcosa di memoria come questo:

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

In Java, Animal[] creatures = new Animal[5];possono essere aperte in memoria in questo modo:

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

Non v'è alcuna diretta analogica per gli array C ++ in linguaggi come Java o Python

Ciò significa che tutti gli oggetti in C ++ array devono essere esattamente lo stesso tipo. Se si vuole costruire qualcosa di simile l'array Java, è necessario utilizzare i puntatori. Si consiglia di utilizzare le classi di smart-puntatore standard std::unique_ptre std::shared_ptr. vale a 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"
Risposto il 19/03/2020 a 22:00
fonte dall'utente

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