C ++ Zuweisung Speicher für die Liste der abstrakten Klasse Objekte

stimmen
0

Mein Verständnis von C ++ Arrays ist, dass Sie nicht ein Array von abstrakten Klasse Objekte zuordnen können, da C ++ nicht weiß, wie Speicher zuweisen für eine noch-zu-sein-entschieden Klassentyp.

Ich habe zusammen ein kleines Beispiel, dass ich verwirrt ein wenig, so ein bisschen mehr fragen wollte

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

Fragen

  1. Wie ist C ++ Lage, den Speicher für dieses Array zuweisen? Warum es nicht beschweren?
  2. Es scheint, etwas über diese nicht alle Objekte wie Tiere ist wegen Versagen, das heißt auf die Behandlung: nicht richtig tun Polymorphismus. Was genau vor sich geht, und warum? Muss ich nur für eine Liste von Zeigern zuweisen diese stattdessen richtig zu machen?

Vielen Dank!

Veröffentlicht am 19/03/2020 um 21:55
quelle vom benutzer
In anderen Sprachen...                            


1 antworten

stimmen
2

Animalist nicht abstrakt. Es enthält keine rein virtuelle Member - Funktionen. Wenn Sie zuweisen cund dauf die Elemente creaturesSie schneiden sie.

Wenn stattdessen Animal::hellohatte rein virtuell deklariert, dh

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

Animal creatures[5]würde nicht kompiliert , da Animalist jetzt abstrakt.


Wie pro Ihre zweite Frage, Runtime - Polymorphismus in C ++ funktioniert nur mit Referenzen und Zeigern. Wenn Sie sich vertraut mit Sprachen wie Java oder Python dies ein wenig seltsam auf den ersten Blick, aber nicht vergessen , dass in diesen Sprachen alle Variablen von Klassentypen sind Zeiger (oder Zeiger artige Dinge, sowieso).

In C ++ Animal creatures[5]wird im Speicher wird in etwa so angelegt:

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

In Java Animal[] creatures = new Animal[5];wird so im Speicher angelegt werden:

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

Es gibt keine direkte Analogie für C ++ Arrays in Sprachen wie Java oder Python

Das bedeutet , dass alle Objekte in einem C ++ Array muss genau die gleiche Art sein. Wenn Sie so etwas wie die Java - Array aufbauen wollen, müssen Sie Zeiger verwenden. Sie sollten die Standard - Smart-Pointer - Klassen verwenden std::unique_ptrund std::shared_ptr. dh

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"
Beantwortet am 19/03/2020 um 22:00
quelle vom benutzer

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