C ++ tildele minne for liste av abstrakte klasse objekter

stemmer
0

Min forståelse av C ++ arrays er at du ikke kan tildele en rekke abstrakte klasse objekter siden C ++ ikke vet hvordan de skal tildele minne for en ennå-å-være-besluttet klasse type.

Jeg satt sammen et lite eksempel som forvirrer meg litt, så ville spørre litt mer

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

spørsmål

  1. Hvordan er C ++ i stand til å allokere minne for denne matrisen? Hvorfor det ikke klage?
  2. Det synes noe om dette ikke unnlate skyldes behandle alle objektene som dyr, det vil si: ikke riktig gjør polymorfisme. Hva er det som skjer, og hvorfor? Må jeg bare nødt til å bevilge for en liste med tips for å gjøre dette riktig i stedet?

Takk!

Publisert på 19/03/2020 klokken 21:55
kilden bruker
På andre språk...                            


1 svar

stemmer
2

Animaler ikke abstrakt. Den inneholder ingen rene virtuelle medlemsfunksjoner. Når du tilordner cog dtil elementer av creaturesdu ha klippet dem.

Hvis du i stedet Animal::hellohadde blitt erklært ren-virtuelle, dvs.

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

Animal creatures[5]ville mislykkes i å kompilere siden Animaler nå abstrakt.


Som per andre spørsmålet, runtime polymorfisme i C ++ fungerer bare med referanser og pekere. Hvis du er kjent med språk som Java eller Python dette kan virke litt rart i begynnelsen, men husk at i disse språkene alle variabler av klassetyper er pekere (eller pekeren-lignende ting, uansett).

I C ++, Animal creatures[5]vil bli lagt ut i minnet noe sånt som dette:

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

I Java, Animal[] creatures = new Animal[5];vil bli lagt ut i minnet som dette:

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

Det er ingen direkte analog for C ++ arrays på språk som Java eller Python

Det betyr at alle objekter i en C ++ matrise må være nøyaktig samme type. Hvis du ønsker å bygge noe som Java array, må du bruke pekere. Du bør bruke standard smart-peker klasser std::unique_ptrog std::shared_ptr. dvs

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"
Svarte 19/03/2020 kl. 22:00
kilden bruker

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