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