Aşağıdaki üçü düşünün struct
:
class blub {
int i;
char c;
blub(const blub&) {}
};
class blob {
char s;
blob(const blob&) {}
};
struct bla {
blub b0;
blob b1;
};
int
4 bayt olan tipik platformlarda , boyutlar, hizalamalar ve toplam dolgu 1 aşağıdaki gibidir:
struct size alignment padding
-------- ------ ----------- ---------
blub 8 4 3
blob 1 1 0
bla 12 4 6
1 boyutu prensipte dolguya "sığabilse bile " blub
ve blob
üyelerin depolanması arasında herhangi bir çakışma yoktur .blob
blub
C ++ 20 no_unique_address
, bitişik boş üyelerin aynı adresi paylaşmasına izin veren özniteliği sunar. Aynı zamanda, yukarıda açıklanan senaryoya göre bir üyenin diğerini depolamak için dolgusu kullanmasına izin verir. Gönderen cppreference (vurgu benim):
Bu veri üyesinin, sınıfındaki diğer tüm statik olmayan veri üyelerinden farklı bir adrese sahip olması gerekmediğini gösterir. Bu, eğer üyenin boş bir türü (örneğin vatansız Allocator) varsa, derleyicinin boş bir taban gibi boş yer kaplamayacak şekilde optimize edebileceği anlamına gelir. Eğer üye boş değilse, içindeki herhangi bir kuyruk dolgusu başka veri üyelerini saklamak için tekrar kullanılabilir.
Gerçekten, eğer bu niteliği kullanırsak blub b0
, bla
damla büyüklüğü 8
, bu yüzden blob
gerçekten blub
godbolt üzerinde görüldüğü gibi saklanır .
Sonunda soruma geçelim:
Standartlardaki hangi metin (C ++ 11 - C ++ 20) no_unique_address
, önemsiz şekilde kopyalanamayan nesneler için bu çakışmayı önler ?
TC nesneleri için, std::memcpy
üye alt nesneler de dahil olmak üzere bir nesneden diğerine izin verilir ve depolama üst üste binmişse bu ( bitişik üye üzerine yazılır) 2 .
1 Dolguyu, basitçe, tüm yapı elemanlarının yapı boyutu ile boyutu arasındaki fark olarak, özyineli olarak hesaplıyoruz.
2 yapmak için: Ben kopya kurucular tanımlanmış olmasının nedeni budur blub
ve blob
değil trivially copyable .