C ++ toewijzen van geheugen voor de lijst van de abstracte klasse objecten

stemmen
0

Mijn kennis van C ++ arrays is dat u een array van abstracte klasse objecten niet kan toewijzen, omdat C ++ niet weet hoe je geheugen toe te wijzen voor een nog-te-worden besloten klasse type.

Ik heb samen een klein voorbeeld dat verwart me een beetje, dus we wilden een beetje meer te vragen

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

vragen

  1. Hoe is C ++ staat om geheugen toe te wijzen voor deze serie? Waarom is het niet klagen?
  2. Het lijkt iets over dit niet falen is te wijten aan de behandeling van alle objecten als dieren, dat wil zeggen: niet goed polymorfisme doen. Wat er precies aan de hand is, en waarom? Moet ik alleen maar toe te wijzen voor een lijst met tips om dit te doen op de juiste plaats?

Bedankt!

De vraag is gesteld op 19/03/2020 om 21:55
bron van user
In andere talen...                            


1 antwoorden

stemmen
2

Animalniet abstract. Het bevat geen pure virtuele lid functies. Wanneer u toewijst cen dde elementen van creaturesje snijden hen.

Als in plaats daarvan, Animal::hellowas verklaard zuiver virtueel, dat wil zeggen

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

Animal creatures[5]zou falen te compileren , omdat Animalnu abstract.


Zoals per uw tweede vraag, runtime polymorfisme in C ++ werkt alleen met referenties en pointers. Als je bekend bent met talen als Java of Python dit een beetje vreemd kan lijken op het eerste, maar vergeet niet dat in die talen alle variabelen van klasse types zijn pointers (of pointer-achtige dingen, in ieder geval).

In C ++, Animal creatures[5]zal worden vastgelegd in het geheugen van iets als dit:

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

In Java, Animal[] creatures = new Animal[5];zal in het geheugen worden vastgelegd als volgt uit:

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

Er is geen directe analoge voor C ++ arrays in talen als Java of Python

Dat betekent dat alle objecten in C ++ array moeten exact hetzelfde type zijn. Als je iets wilt bouwen, zoals de Java-array, moet je pointers. U moet de standaard smart-pointer klassen std::unique_ptren std::shared_ptr. d.w.z

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"
antwoordde op 19/03/2020 om 22:00
bron van user

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