संक्षिप्त उत्तर: सी ++ में, मानों के सरणी कभी भी पॉलिमॉर्फिक नहीं होते हैं, भले ही उनकी सामग्री है, और इसका इलाज नहीं किया जा सकता है। यही है, आप derived ad[N]
का इलाज नहीं कर सकते जैसे कि यह base ab[N]
था।
लंबा उत्तर: इसका कारण सी के सूचक अंकगणितीय में गहराई से दफनाया गया है। यदि आपके पास int* pi
है और इसे ++pi
बढ़ाएं, तो यह केवल अगले मेमोरी पते में वृद्धि नहीं करेगा। यदि ऐसा होता है, तो यह अगले int
पर इंगित नहीं करेगा क्योंकि यह अगले पते पर शुरू नहीं होता है। तो इसके बजाय सूचकांक में sizeof(int)
बाइट जोड़े गए हैं। (एक ठोस उदाहरण मदद कर सकता है:। 8bit char
प्रकार के साथ आर्किटेक्चर पर - char
किया जा रहा है, परिभाषा के द्वारा क्या सी और सी वास्तुकला की बाइट आकार पर विचार ++ - और 32 बिट int
प्रकार, int
4 बाइट्स की आकार की है इस प्रकार, ++pi
4 में जोड़ देगा पॉइंटर्स पता, ताकि यह अगले int
पर इंगित करे।) एक ही अंकगणित अन्य सभी सूचक संचालन पर लागू होता है। तो, उदाहरण के लिए, int* pi2=pi+1
साथ, pi2
sizeof(int)
बाइट्स pi
के पीछे, इंगित करेगा हालांकि pi2-pi
1.
निकलेगा तो, यह मानते हुए आप अंतिम अनुच्छेद समझ में आया, की सरणियों के लिए वापस चलते हैं। यदि आपके पास derived ad[N]
है, तो ad[1]
का पता ad[0]
के पते से अधिक बाइट्स है।(यह समस्या को और जटिल नहीं करने के लिए संरेखण को अनदेखा कर रहा है।) हालांकि, यदि आपके पास base* pb
ad[0]
पर इशारा करते हैं, तो इसे बढ़ाने से यह पहले तत्व के पते के पीछे sizeof(base)
को इंगित करेगा - यदि, यदि (जैसा मामला है आपका उदाहरण) sizeof(base) < sizeof(derived)
, ad[1]
का पता है, लेकिन कहीं ad[0]
के बीच में है।
derived d[5];
derived* begin = d;
const derived* end = d + sizeof(d)/sizeof(d[0]); // points one beyond the last element
while(begin != end)
{
base* pb = begin;
cout<< pb->_bval;
++begin;
}
:
केवल एक चीज आप सरणी सामग्री के इलाज के लिए के रूप में अगर यह सब आधार वर्ग था कर सकते हैं, एक derived*
का उपयोग कर सरणी पर पुनरावृति और पाश भीतर base*
को यह सूचक कास्ट करने के लिए है
(ध्यान दें कि मैंने आपके कोड को C++ 'idiomatic start/end iterators का उपयोग करने के लिए भी बदल दिया है।)
सटीक होने के लिए धन्यवाद। –