Optimasi basis kosong sangat bagus. Namun, ia datang dengan batasan berikut:
Optimalisasi basis kosong dilarang jika salah satu kelas basis kosong juga merupakan tipe atau basis tipe anggota data non-statis pertama, karena dua sub-objek dasar dari tipe yang sama diharuskan memiliki alamat yang berbeda dalam representasi objek dari tipe yang paling diturunkan.
Untuk menjelaskan batasan ini, pertimbangkan kode berikut. The static_assertakan gagal. Sedangkan, mengubah salah satu Fooatau Barsebaliknya mewarisi dari Base2akan mencegah kesalahan:
#include <cstddef>
struct Base {};
struct Base2 {};
struct Foo : Base {};
struct Bar : Base {
Foo foo;
};
static_assert(offsetof(Bar,foo)==0,"Error!");
Saya mengerti perilaku ini sepenuhnya. Apa yang saya tidak mengerti adalah mengapa perilaku tertentu ada . Jelas ditambahkan karena suatu alasan, karena ini merupakan tambahan eksplisit, bukan pengawasan. Apa alasan untuk ini?
Khususnya, mengapa dua sub-proyek dasar harus memiliki alamat yang berbeda? Di atas, Baradalah tipe dan foovariabel anggota tipe itu. Saya tidak melihat mengapa kelas dasar Barpenting untuk kelas dasar dari jenis foo, atau sebaliknya.
Memang, saya jika ada, saya harapkan itu &foosama dengan alamat Barinstance yang berisi itu — seperti yang diperlukan dalam situasi lain (1) . Lagipula, saya tidak melakukan apa-apa dengan virtualwarisan, kelas dasar kosong, dan kompilasi dengan Base2menunjukkan bahwa tidak ada yang rusak dalam kasus khusus ini.
Tetapi jelas alasan ini tidak benar, dan ada situasi lain di mana batasan ini diperlukan.
Katakanlah jawaban harus untuk C ++ 11 atau lebih baru (Saat ini saya menggunakan C ++ 17).
(1) Catatan: EBO ditingkatkan di C ++ 11, dan khususnya menjadi wajib untuk StandardLayoutTypes (meskipun Bar, di atas, bukan a StandardLayoutType).
Base *a = new Bar(); Base *b = a->foo;dengana==b, tetapiadanbjelas merupakan objek yang berbeda (mungkin dengan metode virtual yang berbeda)