Akıllı işaretçileri değere göre döndür.
Söylediğiniz gibi, referans olarak iade ederseniz, referans sayısını doğru bir şekilde artırmayacaksınız, bu da uygun olmayan zamanda bir şeyi silme riskini ortaya çıkarır. Bu tek başına referansla geri dönmemek için yeterli neden olmalıdır. Arayüzler sağlam olmalıdır.
Geri dönüş değeri optimizasyonu (RVO) sayesinde günümüzde maliyet endişesi tartışmalı , bu nedenle modern derleyicilerde bir artırma-artırma-azaltma dizisine veya buna benzer bir şeye maruz kalmayacaksınız. Dolayısıyla, a döndürmenin en iyi yolu shared_ptr
, basitçe değere göre döndürmektir:
shared_ptr<T> Foo()
{
return shared_ptr<T>();
};
Bu, modern C ++ derleyicileri için kesin olmayan bir RVO fırsatıdır. Tüm optimizasyonlar kapatıldığında bile Visual C ++ derleyicilerinin RVO uyguladığını biliyorum. Ve C ++ 11'in hareket semantiği ile bu endişe daha da az alakalı. (Ancak emin olmanın tek yolu profil çizmek ve deney yapmaktır.)
Hala ikna olmadıysanız, Dave Abrahams'ın değere göre geri dönüşü tartışan bir makalesi var. Burada bir pasajı yeniden oluşturuyorum; Gidip makalenin tamamını okumanızı şiddetle tavsiye ederim:
Dürüst olun: Aşağıdaki kod size nasıl hissettiriyor?
std::vector<std::string> get_names();
...
std::vector<std::string> const names = get_names();
Açıkçası, daha iyi bilmem gerekse de bu beni tedirgin ediyor. Prensip olarak, ne zaman get_names()
döner, elimizdeki bir kopyalama vector
ait string
s. Ardından, başlattığımızda onu tekrar
names
kopyalamalıyız ve ilk kopyayı yok etmeliyiz. Vektörde Ns varsa string
, her kopya N + 1 bellek tahsisi ve dizi içeriği kopyalandıkça önbellek dostu olmayan bir dizi veri erişimi gerektirebilir.
Bu tür bir endişeyle yüzleşmek yerine, gereksiz kopyalardan kaçınmak için sık sık referansa geri döndüm:
get_names(std::vector<std::string>& out_param );
...
std::vector<std::string> names;
get_names( names );
Ne yazık ki bu yaklaşım ideal olmaktan uzaktır.
- Kod% 150 büyüdü
const
Bırakmak zorunda kaldık çünkü isimleri değiştiriyoruz.
- İşlevsel programcıların bize hatırlatmayı sevdiği gibi, mutasyon, referans şeffaflığı ve eşitlik mantığını baltalayarak kodu akıl yürütmeyi daha karmaşık hale getirir.
- Artık isimler için katı değer anlamlarına sahip değiliz.
Ancak verimlilik kazanmak için kodumuzu bu şekilde karıştırmak gerçekten gerekli mi? Neyse ki, cevabın hayır olduğu ortaya çıkıyor (ve özellikle C ++ 0x kullanıyorsanız değil).