C ++ přidělování paměti pro seznam abstraktních tříd objektů

hlasů
0

Mé pochopení C ++ polí je, že není možné přidělit řadu abstraktních objektů tříd od C ++ neví, jak alokovat paměť pro ještě-to-be-rozhodnuto typu třídy.

Jsem dal dohromady malý příklad, který zaměňován mě trochu, takže se chtěl zeptat trochu víc

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

otázky

  1. Jak je C ++ schopen přidělit paměť pro toto pole? Proč ne si stěžovat?
  2. Zdá se, něco to není nedostatek je kvůli léčbě všechny předměty jako zvířata, tj není správně dělá polymorfismus. Co přesně se děje, a proč? Ještě budu muset vyčlenit pro seznam ukazatelů, jak to udělat správně místo?

Dík!

Položena 19/03/2020 v 21:55
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
2

Animalnení abstraktní. Neobsahuje žádné čisté členské funkce virtuální. Při přiřazení ca dna prvky creaturesvás se krájení je.

Pokud místo, Animal::hellobyl prohlášen za čistě virtuální, tj

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

Animal creatures[5]by se nepodaří sestavit , protože Animalje nyní abstraktní.


Jak na vaši druhou otázku, runtime polymorfismus v jazyce C ++ pracuje pouze s referencemi a odkazy. Pokud jste obeznámeni s jazyky, jako je Java nebo Python to může zdát trochu divné na první, ale nezapomeňte, že v těchto jazycích všechny proměnné typů tříd jsou ukazatele (nebo ukazatel podobné věci, tak jako tak).

V jazyce C ++, Animal creatures[5]budou stanoveny v paměti něco takového:

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

V Javě, Animal[] creatures = new Animal[5];budou stanoveny v paměti takto:

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

Neexistuje žádný přímý analogový pro C ++ polí v jazycích, jako je Java nebo Python

To znamená, že všechny objekty v C ++ Pole musí být přesně stejný typ. Chcete-li vytvořit něco jako pole Java, je nutné použít ukazatele. Byste měli používat standardní inteligentní ukazatel tříd std::unique_ptra std::shared_ptr. tj

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"
Odpovězeno 19/03/2020 v 22:00
zdroj uživatelem

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