C ++ alocarea de memorie pentru lista de obiecte abstracte de clasă

voturi
0

Înțelegerea mea de C ++ matrice este că nu se poate aloca o serie de obiecte de clasă abstractă, deoarece C ++ nu știe cum să aloce memorie pentru un tip de clasă încă-a-fi decis.

Am pus împreună un pic de exemplu, care confundă-mi un pic, așa că a vrut să ceară un pic mai mult

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

Întrebări

  1. Cum este C ++ capabil de a aloca memorie pentru această matrice? De ce nu se plânge?
  2. Se pare ceva despre acest lucru nu faptul că nu se datorează tratarea tuturor obiectelor ca animale, și anume: nu face corect polimorfism. Ce anume se întâmplă, și de ce? Nu trebuie doar să aloce pentru o listă de indicii pentru a face acest lucru în mod corespunzător în schimb?

Mulțumiri!

Întrebat 19/03/2020 la 21:55
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
2

Animalnu este abstract. Acesta nu conține funcții pure membru virtuale. Când atribuiți cși dla elementele creaturespe care feliere le.

Dacă , în schimb, Animal::helloa fost declarată pură-virtuală, și anume

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

Animal creatures[5]ar nu compila , deoarece Animaleste acum abstractă.


Ca pe a doua întrebare, polimorfism la rulare în C ++ funcționează numai cu referințe și indicii. Dacă sunteți familiarizat cu limbi , cum ar fi Java sau Python acest lucru poate parea un pic ciudat la început, dar amintiți - vă că în aceste limbi toate variabilele de tipuri de clasă sunt indicii (sau pointer-ca lucrurile, oricum).

În C ++, Animal creatures[5]vor fi stabilite în memorie ceva de genul:

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

În Java, Animal[] creatures = new Animal[5];vor fi stabilite în memorie ca aceasta:

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

Nu există nici un analog direct pentru matrice C ++ în limbaje cum ar fi Java sau Python

Asta înseamnă că toate obiectele dintr - un C ++ matrice trebuie să fie exact același tip. Dacă doriți să construiască ceva de genul matrice Java, trebuie să utilizați indicii. Ar trebui să folosiți clasele standard smart-pointer std::unique_ptrși std::shared_ptr. și anume

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"
Publicat 19/03/2020 la 22:00
sursa de către utilizator

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