Ne oluyor ?
Bir oluşturduğunuzda Taxi
, bir Car
alt nesne de oluşturursunuz . Taksi yok edildiğinde, her iki nesne de yok edilir. Aradığınızda by değerini test()
geçersiniz Car
. Böylece bir saniye Car
kopya oluşturulur ve test()
bırakıldığında imha edilir. Bu yüzden 3 yıkıcı için bir açıklamamız var: dizideki ilk ve ikisi.
Dördüncü yıkıcı (dizideki ikinci) beklenmedik ve diğer derleyicilerle çoğaltamadım.
Yalnızca argüman Car
için kaynak olarak geçici olarak yaratılabilir Car
. Doğrudan temin zaman olmaz beri Car
argüman olarak değerini, onu dönüştürme şüpheli Taxi
INTO Car
. Bu beklenmedik bir durum, çünkü Car
her birinde zaten bir alt nesne var Taxi
. Bu nedenle derleyicinin geçici olarak gereksiz bir dönüşüm yaptığını ve bu sıcaklıktan kaçınabilecek kopya seçimini yapmadığını düşünüyorum.
Yorumlarda verilen açıklama:
Burada, dil avukatının iddialarımı doğrulaması standardına referansla açıklama:
- Burada bahsettiğim dönüşüm, yapıcı tarafından bir dönüşüm
[class.conv.ctor]
, yani başka bir türün (burada Taksi) bir argümana dayanan bir sınıfın (burada Araba) bir nesnesinin oluşturulmasıdır.
- Bu dönüşüm daha sonra
Car
değerini döndürmek için geçici bir nesne kullanır . Derleyiciye, [class.copy.elision]/1.1
geçici bir inşa etmek yerine, doğrudan parametreye döndürülecek değeri oluşturabileceğinden, bir kopya seçimine izin verilecektir .
- Eğer bu sıcaklık yan etkiler veriyorsa, bunun nedeni derleyicinin bu olası kopya seçimini kullanmamasıdır. Kopya seçimi zorunlu olmadığı için yanlış değil.
Analizin deneysel teyidi
Şimdi aynı derleyiciyi kullanarak vakanızı yeniden oluşturabilir ve neler olduğunu doğrulamak için bir deneme yapabilirim.
Yukarıdaki varsayımım, derleyicinin Car(const &Taxi)
doğrudan Car
alt nesnesinden kopya oluşturma yerine yapıcı dönüşümünü kullanarak bir alt parametre geçirme işlemini seçmesiydi Taxi
.
Bu yüzden aramayı denedim test()
ama açıkça Taxi
bir Car
.
İlk denemem durumu iyileştirmeyi başaramadı. Derleyici hala yetersiz yapıcı dönüşümünü kullanıyordu:
test(static_cast<Car>(taxi)); // produces the same result with 4 destructor messages
İkinci denemem başarılı oldu. Dökümü de yapar, ancak derleyiciye bu aptalca geçici nesneyi oluşturmadan ve Car
alt Taxi
nesnesini kullanmasını şiddetle önermek için işaretçi dökümünü kullanır :
test(*static_cast<Car*>(&taxi)); // :-)
Ve sürpriz: beklendiği gibi çalışıyor, sadece 3 imha mesajı üretiyor :-)
Sonuç deneyi:
Son bir denemede, dönüşümle özel bir oluşturucu sağladım:
class Car {
...
Car(const Taxi& t); // not necessary but for experimental purpose
};
ve uygulamak *this = *static_cast<Car*>(&taxi);
. Aptalca geliyor, ancak bu aynı zamanda sadece 3 yıkıcı mesajı görüntüleyecek ve böylece gereksiz geçici nesneden kaçınacak kod üretir.
Bu, derleyicide bu davranışa neden olan bir hata olabileceğini düşünmeye yol açar. Bazı durumlarda temel sınıftan doğrudan kopya oluşturma olasılığı kaçırılmış olabilir.
Taxi
bir alarak bir işleve nesneyiCar
değeriyle nesneyi?