Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ขนาดของ Object ของ Empty Class ใน C++

ภาพรวม

ใน C++ Empty Class (ไม่มี Non-Static Data Members) มีขนาดอย่างน้อย 1 Byte เพื่อให้ Object แต่ละตัวมี Address ที่ไม่ซ้ำกัน (Unique Address) ตามกฎของ C++ Standard

ตัวอย่างโค้ด

#include <iostream>
using namespace std;

class Empty {};           // Empty Class
class NonEmpty {          // Non-Empty Class
    int data;
public:
    void func() {}
};

int main() {
    Empty e1, e2;
    NonEmpty n1, n2;
    
    cout << "Size of Empty class: " << sizeof(Empty) << "\n";
    cout << "Size of NonEmpty class: " << sizeof(NonEmpty) << "\n";
    cout << "Size of Empty object: " << sizeof(e1) << "\n";
    cout << "Size of NonEmpty object: " << sizeof(n1) << "\n";
    
    cout << "\nAddress of e1: " << &e1;
    cout << "\nAddress of e2: " << &e2;
    cout << "\nAddresses are different: " << (&e1 != &e2) << "\n";
    
    return 0;
}

ผลลัพธ์

Size of Empty class: 1
Size of NonEmpty class: 4
Size of Empty object: 1
Size of NonEmpty object: 4
Address of e1: 0x7ffc1234
Address of e2: 0x7ffc1235
Addresses are different: 1

ทำไมต้องเป็น 1 Byte?

  1. Unique Address Requirement: C++ Standard กำหนดว่า Object ทุกตัวต้องมี Address ที่แตกต่างกัน (&obj1 != &obj2)
  2. Array Support: ถ้า Size = 0, Empty arr[10] จะมีขนาด 0 → ทุก Element ชี้ Address เดียวกัน
  3. Pointer Arithmetic: ptr + 1 ต้องชี้ Object ถัดไปได้

Empty Base Optimization (EBO)

Compiler Optimization ที่ทำให้ Empty Base Class **ไม่ใช้พื้นที่** ใน Derived Class:


class EmptyBase {};  // Size = 1

class Derived : public EmptyBase {
    int data;  // Size = 4 (ไม่ใช่ 5!)
};

int main() {
    cout << sizeof(EmptyBase) << "\n";   // 1
    cout << sizeof(Derived) << "\n";     // 4 (EBO Applied!)
}

เงื่อนไข EBO

  • Base Class ต้องเป็น Empty (No Non-Static Data Members)
  • Derived Class ต้องไม่มี Base Class อื่นที่ Empty และ Type เดียวกัน (No Ambiguity)
  • Multiple Inheritance: EBO ทำงานได้หลาย Base ถ้า Type ต่างกัน

ขนาดในกรณีต่างๆ

ประเภทขนาด (Typical 64-bit)หมายเหตุ
Empty Class1 ByteMinimum Size
Class with int4 Bytesint = 4 bytes
Class with int + double16 BytesAlignment: double ต้อง 8-byte aligned
Empty Base + int (EBO)4 BytesEmpty Base ไม่เพิ่ม Size
Two Empty Bases (Different Types)1 ByteEBO ทั้งคู่ Overlap ได้
Virtual Function (vptr)8 Bytes (64-bit)Pointer to vtable
Virtual Inheritance+8 Bytes (vbptr)Virtual Base Pointer

C++20: [[no_unique_address]]


struct NonEmpty {
    int data;
    [[no_unique_address]] EmptyBase base;  // Force EBO-like behavior for Member
    // Size = 4 (แทนที่จะเป็น 8)
};

สรุป

  • Empty Class = 1 Byte (Minimum)
  • EBO ทำให้ Empty Base Class ไม่เพิ่มขนาด Derived Class
  • ใช้ Empty Classes สำหรับ Tags, Policies, Mixins ได้โดยไม่เสีย Memory
  • [[no_unique_address]] (C++20) ขยาย EBO ให้ Member Variables ด้วย