इस उदाहरण पर विचार करें:
#include <iostream>
int main()
{
struct A {};
struct B : A {};
struct C : A, B {};
std::cout << sizeof(A) << '\n'; // 1
std::cout << sizeof(B) << '\n'; // 1
std::cout << sizeof(C) << '\n'; // 2, because of a duplicate base
struct E : A {virtual ~E() {}};
struct F : A, B {virtual ~F() {}};
std::cout << sizeof(E) << '\n'; // 8, the base overlaps the vtable pointer
std::cout << sizeof(F) << '\n'; // 16, but why?
}
यहां आप देख सकते हैं कि struct Eखाली बेस क्लास के लिए (जो कि 1 बाइट बड़ी है) अपेक्षा के अनुरूप वाइबेटर पॉइंटर के समान स्टोरेज का उपयोग करता है।
लेकिन struct Fजिसके लिए डुप्लिकेट खाली आधार है, ऐसा नहीं होता है। इसका क्या कारण है?
मुझे GCC, Clang और MSVC पर समान परिणाम मिलते हैं। उपरोक्त परिणाम x64 के लिए हैं, इसलिए sizeof(void *) == 8।
दिलचस्प बात यह है कि struct G : A, B {void *ptr;};GCC और Clang के लिए EBO (आकार 8 है) प्रदर्शन करते हैं, लेकिन MSVC नहीं है (आकार 16 है)।
Cऔर F? आखिरकार, 2 * sizeof(void*) == 16जैसा आपने कहा है x86_64 पर। कंपाइलर पूरी तरह से अनुकूलन नहीं कर सकता (जैसा कि स्टोरी टेलर ने कहा) और ऐसा नहीं है।
A, जिसके माध्यम से विरासत में मिला है B, उसे एक्सेस नहीं किया जा सकता है। यह ठीक है। केवल अगर आप वास्तव में इसे एक्सेस करने की कोशिश करते हैं, जैसा कि आपके उदाहरण में, आपको एक त्रुटि मिलती है।
C(जो विरासत में मिला है ) से विरासत में मिलाA,Bआपको विरासत में मिला फॉर्मAऔरBसीधे