C ++ özet sınıf nesneleri listesini bellek ayrılırken

oy
0

C ++ Dizilerin Benim anlayış C ++ henüz-to-karara sınıf türü için bellek ayrılamadı bilmiyor beri soyut sınıf nesneleri dizisi tahsis edemez olmasıdır.

Ben karıştırır bana biraz, yani biraz daha fazla sormak istediğini Birlikte küçük bir örnek koymak

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

Sorular

  1. Nasıl C Bu dizi için bellek ayrılamadı mümkün ++ nedir? Neden şikayet etmiyor?
  2. Düzgün polimorfizm yapmıyor: Bu başarısız değil bu yani Hayvanlar gibi tüm nesneleri, tedavi nedeniyle hakkında bir şeyler belirir. Tam olarak ne oluyor ve neden? Sadece düzgün yerine bunu yapmak için işaretçiler listesi için tahsis etmek var mı?

Teşekkürler!

Oluştur 19/03/2020 saat 21:55
kaynak kullanıcı
Diğer dillerde...                            


1 cevaplar

oy
2

Animalsoyut değil. Hiçbir saf sanal üye işlevleri içerir. Ne zaman atamak cve delemanları için creaturessize edilir dilimleme onları.

Eğer bunun yerine, Animal::helloilan edilen saf sanal, yani

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

Animal creatures[5]olur derlemek için başarısız beri Animalartık soyut.


İkinci soruya göre, C ++ çalışma zamanı polimorfizmi sadece referansları ve işaretçiler ile çalışır. Bu ilk başta biraz tuhaf görünüyordu, ancak bu dillerde hatırlayabiliriz Java veya Python gibi diller ile sen tanıdık olursa sınıf türlerinin tüm değişkenleri noktalar şunlardır (veya işaretçi benzeri şeyler, her neyse).

C ++, Animal creatures[5]böyle hafıza şey düzenlenir:

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

Java da, Animal[] creatures = new Animal[5];böyle bellekte şekilde düzenlenir:

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

Java veya Python gibi dillerde C ++ diziler için hiçbir doğrudan analog yoktur

Bu demektir ki, bir C tüm nesneler ++ dizi aynı tip olmalıdır. Java dizisi gibi bir şey inşa etmek istiyorsanız, işaretçileri kullanmak gerekir. Standart akıllı işaretçi sınıfları kullanmalıdır std::unique_ptrve std::shared_ptr. yani

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"
Cevap 19/03/2020 saat 22:00
kaynak kullanıcı

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