Yazarken kopyalamanın olası avantajlarının neler olduğunu merak ediyorum. Doğal olarak, kişisel görüşler beklemiyorum, ancak somut bir şekilde teknik ve pratik olarak faydalı olabileceği gerçek dünyadaki pratik senaryolar. Somut olarak, bir &
karakteri yazmaktan daha fazlasını kastediyorum .
Açıklığa kavuşturmak için, bu soru, atama veya kopya oluşturma işleminin örtük bir sığ kopya oluşturduğu, ancak üzerinde yapılan değişikliklerin gizli bir derin kopya oluşturduğu ve değişiklikleri orijinal nesne yerine uyguladığı veri türleri bağlamındadır.
Sormamın nedeni, varsayılan örtük davranış olarak COW'a sahip olmanın herhangi bir faydasını bulamıyorum. Birçok veri türü için COW uygulanmış olan Qt, neredeyse hepsinin altında dinamik olarak ayrılmış depolama alanı var. Peki kullanıcıya gerçekten nasıl fayda sağlar?
Bir örnek:
QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource
qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
// s is still "some text"
Bu örnekte COW kullanarak ne kazanıyoruz?
Yapmak istediğimiz tek şey const işlemlerini kullanmaksa s1
gereksizdir, kullanmak da mümkündür s
.
Değeri değiştirmek niyetindeysek, COW, kaynak kopyayı yalnızca ilk sabit olmayan işleme kadar, örtülü paylaşım için ref sayımını arttırma ve paylaşılan depolama biriminden ayırma maliyetini (minimum da olsa) erteler. COW ile ilgili tüm ek yükün anlamsız olduğu anlaşılıyor.
Parametre geçirme bağlamında çok farklı değildir - değeri değiştirmek istemiyorsanız, const referansı olarak geçin, değiştirmek istiyorsanız, değiştirmek istemiyorsanız örtük bir derin kopya yaparsınız orijinal nesneyi veya değiştirmek istiyorsanız referans ile iletin. Yine COW, hiçbir şey elde etmeyen gereksiz bir ek yük gibi görünüyor ve herhangi bir değişiklik orijinal nesneden ayrılacağından, istediğinizde bile orijinal değeri değiştiremeyeceğiniz bir sınırlama ekliyor.
Bu nedenle, COW hakkında bilgi sahibi olmanıza veya habersiz olmanıza bağlı olarak, ya belirsiz niyet ve gereksiz yük ile kodla sonuçlanabilir veya beklentileri karşılamayan ve başınızı çizmenize neden olan tamamen kafa karıştırıcı bir davranışla sonuçlanabilir.
Bana göre, gereksiz derin bir kopyadan kaçınmak isteyip istemediğiniz veya daha fazlasını yapmak isteyip istemediğiniz daha verimli ve daha okunabilir çözümler var gibi görünüyor. Peki COW'un pratik yararı nerededir? Bu kadar popüler ve güçlü bir çerçevede kullanıldığı için bazı faydalar olduğunu varsayıyorum.
Ayrıca, okuduğum kadarıyla, COW artık C ++ standart kütüphanesinde açıkça yasaklanmıştır. İçinde gördüğüm con'ların bununla bir ilgisi olup olmadığını bilmiyorum, ama her iki durumda da bunun bir nedeni olmalı.
[]
operatörü kullansanız da çok kötü bir tasarım gibi görünür . Yani COW kötü tasarıma izin veriyor - bu pek bir faydası yok gibi görünüyor :) Son paragraftaki nokta geçerli görünüyor, ama ben kendimi örtük davranışların büyük bir hayranı değilim - insanlar bunu kabul etmek için eğilimlidirler ve sonra kodun neden beklendiği gibi çalışmadığını anlamak zor bir zaman ve örtük davranışın arkasında neyin gizlendiğini kontrol edene kadar merak etmeye devam edin.