เหตุใดขนาดของคลาสใน c ++ ขึ้นอยู่กับสถานะสาธารณะ / ส่วนตัวของสมาชิกข้อมูล


23

จากสิ่งที่ฉันรู้ขนาดของคลาสใน c ++ ขึ้นอยู่กับปัจจัยด้านล่าง -

  1. ขนาดของสมาชิกข้อมูลที่ไม่คงที่ทั้งหมด
  2. ลำดับของสมาชิกข้อมูล
  3. หากเปิดใช้งานการเสริมไบต์แล้วหรือไม่
  4. ขนาดของคลาสฐานทันที
  5. การมีอยู่ของฟังก์ชั่นเสมือนจริง
  6. โหมดของการสืบทอด (การสืบทอดเสมือน)

ตอนนี้ฉันได้สร้าง 2 ชั้นดังนี้

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

ตอนนี้ในการตรวจสอบขนาดของ A และ BI เห็น

  • ขนาดของ A: 16
  • ขนาด B: 16

สมมติฐานของฉันคือถ่าน c ในคลาส B รองรับใน "หลุม" ที่เหลืออยู่ในคลาส A

แต่สิ่งที่ทำให้ฉันสับสนคือสถานการณ์ด้านล่างที่ทำให้ฉันเปิดเผยต่อสมาชิก

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

ตอนนี้กลายเป็นขนาด

  • ขนาดของ A: 16
  • ขนาด B: 20

ฉันไม่สามารถเข้าใจเหตุผลของความแตกต่างนี้ได้


1
เหตุใดขนาดของคลาสใน c ++ ขึ้นอยู่กับสถานะสาธารณะ / ส่วนตัวของสมาชิกข้อมูล - ไม่ได้ เหล่านี้คือรายละเอียดการใช้งานของคอมไพเลอร์
PaulMcKenzie

1
ดังนั้นคุณใช้คอมไพเลอร์อะไร?
Romen

2
@PaulMcKenzie จริงๆแล้วมันทำ คำสั่งมาตรฐานสมาชิกที่มีการเข้าถึงเดียวกันได้รับการจัดกลุ่มเข้าด้วยกันดังนั้นการเปลี่ยนแปลงที่จะเปลี่ยนกลยุทธ์การขยายของคอมไพเลอร์
NathanOliver

@ NathanOliver-ReinstateMonica ฉันไม่รู้ คุณมีการอ้างอิงถึงส่วนที่เกี่ยวข้องมีประโยชน์โดยโอกาสใด ๆ ?
R Sahu

@RSahu เงยหน้าขึ้นมองคำตอบของฉันแน่นในตอนนี้
NathanOliver

คำตอบ:


8

Itanium ABI ใช้นิยาม C ++ 03 ของ PODเพื่อกำหนดคลาสที่เป็น "POD สำหรับวัตถุประสงค์ของโครงร่าง" การมีสมาชิกข้อมูลส่วนตัวทำให้คลาสไม่เหมาะสมจากการเป็นผลรวมและ POD ใน C ++ 03:

POD-structเป็นชั้นรวมที่ไม่มีไม่คงที่ข้อมูลสมาชิกประเภทที่ไม่ใช่ POD-struct ไม่ใช่ POD ยูเนี่ยน (หรืออาร์เรย์ของชนิดดังกล่าว) หรือการอ้างอิงและมีผู้ประกอบการที่ได้รับมอบหมายสำเนาที่ผู้ใช้กำหนดและไม่มีการ destructor ที่ผู้ใช้กำหนด

การเป็นคลาส POD จะปิดการใช้งานการเติมหางซ้ำ :

dsize, nvsize และ nvalign ของประเภทเหล่านี้ถูกกำหนดให้เป็นขนาดปกติและการจัดตำแหน่ง คุณสมบัติเหล่านี้มีความสำคัญสำหรับประเภทคลาสที่ไม่ว่างที่ใช้เป็นคลาสพื้นฐานเท่านั้น เราไม่สนใจการขยายส่วนท้ายสำหรับ POD เนื่องจากมาตรฐานรุ่นแรกไม่อนุญาตให้เราใช้เพื่อสิ่งอื่นและบางครั้งอนุญาตให้คัดลอกประเภทได้เร็วขึ้น

ดังนั้นในตัวอย่างแรกของคุณAไม่ใช่ POD สำหรับจุดประสงค์ของเค้าโครงและสามารถใช้การเสริมท้ายได้B::cแต่ในตัวอย่างที่สองของคุณคือ POD และไม่สามารถนำกลับมาใช้ใหม่ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.