Mengapa ukuran kelas dalam c ++ bergantung pada status publik / pribadi anggota data?

23

Dari apa yang saya tahu, ukuran kelas di c ++ tergantung pada faktor-faktor di bawah ini -

  1. Ukuran semua anggota data non-statis.
  2. Urutan anggota data.
  3. Jika byte padding diaktifkan atau tidak.
  4. Ukuran kelas dasar langsungnya.
  5. Adanya fungsi virtual.
  6. Mode pewarisan (virtual inheritance).

Sekarang saya telah membuat 2 kelas seperti di bawah ini -

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;  
};

sekarang di cek ukuran A dan BI lihat

  • ukuran A: 16
  • ukuran B: 16

Asumsi saya adalah char c di kelas B ditampung di "hole" yang tersisa di kelas A.

Tapi, yang membingungkan saya adalah skenario di bawah ini di mana saya membuat anggota publik

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

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

Sekarang ukurannya menjadi

  • ukuran A: 16
  • ukuran B: 20

Saya sepertinya tidak mengerti alasan perbedaan ini.

J.DOE
sumber
1
Mengapa ukuran kelas dalam c ++ bergantung pada status publik / pribadi anggota data? - Tidak. Itu adalah detail implementasi yang bergantung pada compiler.
PaulMcKenzie
1
Jadi kompiler apa yang Anda gunakan?
Romen
2
@ PaulMcKenzie Sebenarnya begitu. Mandat standar anggota dengan akses yang sama dikelompokkan bersama sehingga mengubah yang akan mengubah strategi padding dari kompiler.
NathanOliver
@ NathanOliver-ReinstateMonica, saya tidak tahu itu. Apakah Anda memiliki referensi ke bagian yang relevan berguna secara kebetulan?
R Sahu
@RSahu Mencari itu untuk memasukkan jawaban saya sekarang.
NathanOliver

Jawaban:

8

ABI Itanium menggunakan definisi C ++ 03 dari POD untuk mendefinisikan kelas yang "POD untuk keperluan tata letak". Memiliki anggota data pribadi mendiskualifikasi kelas dari menjadi agregat dan karenanya POD dalam C ++ 03:

Sebuah POD-struct adalah kelas agregat yang tidak memiliki anggota data non-statis jenis non-POD-struct, non-POD-serikat (atau array dari jenis tersebut) atau referensi, dan tidak memiliki operator yang copy tugas yang ditetapkan pengguna dan tidak ada destructor yang ditentukan pengguna.

Menjadi kelas POD menonaktifkan reuse padding :

Dsize, nvsize, dan nvalign dari tipe-tipe ini didefinisikan sebagai ukuran dan penyelarasannya yang biasa. Properti ini hanya penting untuk tipe kelas non-kosong yang digunakan sebagai kelas dasar. Kami mengabaikan bantalan ekor untuk POD karena versi awal dari standar tidak memungkinkan kami untuk menggunakannya untuk hal lain dan karena terkadang memungkinkan penyalinan jenis yang lebih cepat.

Jadi, dalam contoh pertama Anda, Abukan POD untuk tujuan tata letak dan bantalan ekornya dapat digunakan untuk B::c, tetapi dalam contoh kedua Anda, itu adalah POD, dan bantalan ekornya tidak dapat digunakan kembali.

TC
sumber