खाली आधार अनुकूलन महान है। हालाँकि, यह निम्नलिखित प्रतिबंध के साथ आता है:
खाली आधार अनुकूलन निषिद्ध है यदि खाली आधार वर्गों में से एक भी प्रकार या पहले गैर-स्थैतिक डेटा सदस्य के प्रकार का आधार है, क्योंकि ऑब्जेक्ट के प्रतिनिधित्व के भीतर अलग-अलग पते होने के लिए एक ही प्रकार के दो आधार उप-खंडों की आवश्यकता होती है सबसे व्युत्पन्न प्रकार का।
इस प्रतिबंध की व्याख्या करने के लिए, निम्नलिखित कोड पर विचार करें। static_assertअसफल हो जायेगी। जबकि, Fooया तो या Barबदले से इनहेरिट करने से Base2त्रुटि हो जाएगी:
#include <cstddef>
struct Base {};
struct Base2 {};
struct Foo : Base {};
struct Bar : Base {
Foo foo;
};
static_assert(offsetof(Bar,foo)==0,"Error!");
मैं इस व्यवहार को पूरी तरह से समझता हूं। मुझे समझ में नहीं आता है कि यह विशेष व्यवहार क्यों मौजूद है । यह स्पष्ट रूप से एक कारण के लिए जोड़ा गया था, क्योंकि यह एक स्पष्ट जोड़ है, न कि एक निरीक्षण। इसके लिए तर्क क्या है?
विशेष रूप से, अलग-अलग पते के लिए दो आधार उप-विषयों की आवश्यकता क्यों होनी चाहिए? उपरोक्त में, Barएक प्रकार है और fooउस प्रकार का एक सदस्य चर है। मैं यह नहीं देखता कि आधार Barके प्रकार foo, या इसके विपरीत के आधार वर्ग के मामलों का आधार वर्ग क्यों है ।
वास्तव में, अगर मुझे कुछ भी होता है, तो मैं उम्मीद करूंगा कि &fooयह उस Barउदाहरण के पते के समान होगा, जैसे कि अन्य स्थितियों में होना आवश्यक है (1) । सब के बाद, मैं virtualविरासत के साथ कुछ भी कल्पना नहीं कर रहा हूं, बेस कक्षाएं परवाह किए बिना खाली हैं, और संकलन से Base2पता चलता है कि इस विशेष मामले में कुछ भी नहीं टूटता है।
लेकिन स्पष्ट रूप से यह तर्क किसी भी तरह से गलत है, और ऐसी अन्य परिस्थितियां हैं जहां इस सीमा की आवश्यकता होगी।
मान लें कि उत्तर C ++ 11 या नए के लिए होना चाहिए (मैं वर्तमान में C ++ 17 का उपयोग कर रहा हूं)।
(1) नोट: EBO C ++ 11 में अपग्रेड हो गया, और इन- StandardLayoutTypeएस के लिए विशेष रूप से अनिवार्य हो गया (हालांकि Bar, ऊपर, यह नहीं है StandardLayoutType)।
Base *a = new Bar(); Base *b = a->foo;के साथa==bहै, लेकिनaऔरbस्पष्ट रूप से विभिन्न वस्तुओं (शायद अलग आभासी विधि ओवरराइड के साथ) कर रहे हैं।