C ++ alocação de memória para lista de objetos classe abstrata

votos
0

O meu entendimento de matrizes C ++ é que você não pode alocar uma matriz de objetos classe abstrata desde C ++ não sabe como alocar memória para um tipo de classe ainda-a-ser-decidido.

Eu coloquei um pequeno exemplo que me confunde um pouco, por isso queria pedir um pouco mais

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

Questões

  1. Como é C ++ capaz de alocar memória para essa matriz? Por que ele não reclamar?
  2. Parece algo sobre isso não não é devido ao tratamento de todos os objetos como animais, ou seja: não fazendo corretamente polimorfismo. O que exatamente está acontecendo e por quê? Eu só tenho para alocar para uma lista de ponteiros para fazer isso corretamente em vez disso?

Obrigado!

Publicado 19/03/2020 em 21:55
fonte usuário
Em outras línguas...                            


1 respostas

votos
2

Animalnão é abstrato. Ele não contém funções membro virtuais puras. Quando você atribui ce daos elementos de creaturesque você está cortando -los.

Se em vez disso, Animal::hellotinha sido declarado puro-virtual, ou seja,

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

Animal creatures[5]que não compilar desde Animalagora é abstrato.


Como por sua segunda pergunta, tempo de execução polimorfismo em C ++ só funciona com referências e ponteiros. Se você estiver familiarizado com linguagens como Java ou Python isso pode parecer um pouco estranho no início, mas lembre-se que nessas línguas todas as variáveis de tipos de classe são ponteiros (ou ponteiro-como coisas, de qualquer maneira).

Em C ++, Animal creatures[5]será colocado para fora em algo memória como esta:

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

Em Java, Animal[] creatures = new Animal[5];será colocado para fora na memória como esta:

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

Não há nenhuma analogia direta para matrizes C ++ em linguagens como Java ou Python

Isso significa que todos os objetos em um C ++ matriz deve ser exatamente o mesmo tipo. Se você quer construir algo como a matriz Java, você deve usar ponteiros. Você deve usar as classes de ponteiro inteligente padrão std::unique_ptre std::shared_ptr. ou seja

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"
Respondeu 19/03/2020 em 22:00
fonte usuário

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