Boş taban optimizasyonu harika. Ancak, aşağıdaki kısıtlama ile birlikte gelir:
Aynı tabandaki iki temel alt nesnenin nesne temsili içinde farklı adreslere sahip olması gerektiğinden, boş taban sınıflarından birinin de ilk statik olmayan veri üyesinin türü veya tabanı olması durumunda boş taban optimizasyonu yasaktır. türetilmiştir.
Bu kısıtlamayı açıklamak için aşağıdaki kodu göz önünde bulundurun. static_assertBaşarısız olur. Halbuki ikisinden birini değiştirmek ya Fooda Bardevralmak yerine Base2hatayı önlemek için:
#include <cstddef>
struct Base {};
struct Base2 {};
struct Foo : Base {};
struct Bar : Base {
Foo foo;
};
static_assert(offsetof(Bar,foo)==0,"Error!");
Bu davranışı tamamen anlıyorum. Ne yapmak değil anlamaya olduğunu neden bu özel davranış var . Bir nedenden dolayı açık bir şekilde eklenmiştir, çünkü açık bir eklenti, bir gözetim değil. Bunun mantığı nedir?
Özellikle, iki temel alt nesnenin neden farklı adreslere sahip olması gerekir? Yukarıda, Barbir türdür ve foobu türün bir üye değişkenidir. Temel sınıfın neden temel sınıf Bartürüyle ilgili olduğunu anlamıyorum fooveya tam tersi.
Gerçekten de, eğer bir şey varsa, bunun onu içeren örneğin &fooadresi ile aynı olmasını beklerdim Bar- diğer durumlarda olması gerektiği gibi (1) . Sonuçta, virtualkalıtımla süslü bir şey yapmıyorum , temel sınıflar ne olursa olsun boş ve bu derleme Base2, bu özel durumda hiçbir şeyin kırılmadığını gösteriyor.
Ancak bu mantık bir şekilde yanlıştır ve bu sınırlamanın gerekli olacağı başka durumlar da vardır.
Diyelim ki cevaplar C ++ 11 veya daha yeni bir sürüm için olmalı (şu anda C ++ 17 kullanıyorum).
(1) Not: EBO, C ++ 11'de yükseltildi ve özellikle StandardLayoutTypes için zorunlu hale geldi (ancak Bar, yukarıda a değil StandardLayoutType).
Base *a = new Bar(); Base *b = a->foo;ilea==b, ancakavebaçıkça (belki farklı sanal yöntem geçersiz kılma özelliği olan) farklı nesnelerdir.