C ++ κατανομή μνήμης για τη λίστα των αντικειμένων αφηρημένη κατηγορία

ψήφοι
0

Η κατανόησή μου της C ++ συστοιχίες είναι ότι δεν μπορεί να διαθέσει μια σειρά από αντικείμενα αφηρημένη κατηγορία δεδομένου ότι η 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();
}

ερωτήσεις

  1. Πώς είναι C ++ σε θέση να διαθέσει μνήμης για αυτή την σειρά; Γιατί δεν διαμαρτύρονται;
  2. Φαίνεται κάτι γι 'αυτό δεν την αποτυχία οφείλεται στην θεραπεία όλων των αντικειμένων όπως τα ζώα, δηλαδή: δεν κάνει σωστά πολυμορφισμό. Τι ακριβώς συμβαίνει και γιατί; Μπορώ μόνο να διαθέσουν για μια λίστα από δείκτες για να γίνει αυτό σωστά αντ 'αυτού;

Ευχαριστώ!

Δημοσιεύθηκε 19/03/2020 στις 21:55
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
2

Animalδεν είναι αφηρημένη. Δεν περιέχει καθαρή λειτουργίες εικονικών μελών. Όταν εκχωρείτε cκαι dνα τα στοιχεία creaturesπου τεμαχισμό τους.

Αν, αντίθετα, Animal::helloείχε δηλώσει καθαρά-εικονική, δηλαδή

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

Animal creatures[5]θα αποτύχει να συγκεντρώσει δεδομένου ότι Animalείναι τώρα αφηρημένο.


Σύμφωνα με το δεύτερο ερώτημά σας, το χρόνο εκτέλεσης πολυμορφισμός σε C ++ λειτουργεί μόνο με αναφορές και δείκτες. Αν είστε εξοικειωμένοι είστε με γλώσσες όπως η Java ή Python, αυτό μπορεί να φαίνεται λίγο περίεργο στην αρχή, αλλά να θυμάστε ότι σε αυτές τις γλώσσες όλες οι μεταβλητές των τύπων κατηγορίας είναι δείκτες (ή δείκτης-όπως τα πράγματα, έτσι κι αλλιώς).

Στη C ++, Animal creatures[5]που θα είναι έξω σε κάτι μνήμη σαν αυτό:

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

Στην Java, Animal[] creatures = new Animal[5];θα πρέπει να καθορίζονται στην μνήμη σαν αυτό:

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

Δεν υπάρχει άμεση αναλογική για την C ++ συστοιχίες σε γλώσσες όπως η Java ή Python

Αυτό σημαίνει ότι όλα τα αντικείμενα σε C ++ σειρά πρέπει να είναι ακριβώς το ίδιο είδος. Αν θέλετε να δημιουργήσετε κάτι σαν την σειρά Java, θα πρέπει να χρησιμοποιήσετε δείκτες. Θα πρέπει να χρησιμοποιήσετε τις τυπικές τάξεις smart-δείκτη std::unique_ptrκαι std::shared_ptr. δηλαδή

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"
Απαντήθηκε 19/03/2020 στις 22:00
πηγή χρήστη

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