सी ++ सार वर्ग वस्तुओं की सूची के लिए स्मृति का आवंटन

वोट
0

सी ++ सरणियों की मेरी समझ है कि आप अमूर्त वर्ग वस्तुओं की एक सरणी आवंटित नहीं कर सकता, क्योंकि सी ++ एक अभी तक हो-का फैसला किया वर्ग प्रकार के लिए स्मृति को आबंटित करने के लिए कैसे पता नहीं है।

मैं एक साथ एक छोटे से उदाहरण रखा है कि मुझे भ्रमित एक सा है, तो थोड़ा और पूछना चाहते

#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. कैसे सी इस सरणी के लिए स्मृति को आबंटित करने में सक्षम है ++? यह क्यों शिकायत नहीं करता है?
  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 ++ क्रम बहुरूपता केवल संदर्भ और संकेत के साथ काम करता है। इस पहली बार में अजीब एक सा लग सकता है, लेकिन याद रखें कि उन भाषाओं में यदि आप जावा या पायथन जैसी भाषाओं के साथ हैं परिचित वर्ग प्रकार के सभी चर संकेत दिए गए हैं (या सूचक की तरह बातें, वैसे भी)।

C ++ में, Animal creatures[5]इस तरह स्मृति कुछ में बाहर रखी हो जाएगा:

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

जावा में, Animal[] creatures = new Animal[5];इस तरह स्मृति में बाहर रखी हो जाएगा:

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

वहाँ जावा या पायथन जैसी भाषाओं में सी ++ सरणियों के लिए कोई सीधा एनालॉग है

इसका मतलब है कि एक सी में सभी वस्तुओं ++ सरणी ठीक उसी प्रकार होना चाहिए कि। आप जावा सरणी की तरह कुछ का निर्माण करना चाहते हैं, तो आप संकेत का उपयोग करना चाहिए। आप मानक स्मार्ट सूचक वर्गों का उपयोग करना चाहिए 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