Genel olarak en iyi uygulama tavsiye edilebilir kullanılan 1 için için Const ref kullanımı geçişte her türlü türlü (yerleşik haricinde char
, int
, double
yineleyicileri için, vs.) ve fonksiyon nesneler için (elde edilen lambda'lar, sınıflar std::*_function
).
Bu, özellikle hareket semantiğinin varlığından önce doğruydu . Nedeni basit: Eğer değere göre geçtiyseniz, nesnenin bir kopyasının yapılması gerekiyordu ve çok küçük nesneler dışında, bu her zaman bir referans geçirmekten daha pahalıdır.
C ++ 11 ile hareket semantiği kazandık . Özetle, hareket semantiği, bazı durumlarda, bir nesnenin kopyalanmadan “değere göre” geçirilmesine izin verir. Özellikle, bu geçirmeden o nesne bir olan durumdur rvalue .
Kendi başına, bir nesneyi hareket ettirmek hala en azından referans yoluyla geçmek kadar pahalıdır. Bununla birlikte, birçok durumda bir işlev zaten bir nesneyi dahili olarak kopyalar - yani argümanın sahipliğini alır . 2
Bu durumlarda aşağıdaki (basitleştirilmiş) ödünleşime sahibiz:
- Nesneyi referans olarak geçebilir, sonra dahili olarak kopyalayabiliriz.
- Nesneyi değere göre aktarabiliriz.
"Değere göre aktar", nesne bir değer olmadıkça nesnenin kopyalanmasına neden olur. Bir rvalue durumunda, nesne hareket ettirilebilir, böylece ikinci durum aniden artık “kopyala, sonra taşı” değil, “taşı, sonra (muhtemelen) tekrar hareket et” olur.
Uygun hareket yapıcılarını (vektörler, dizeler… gibi) uygulayan büyük nesneler için, ikinci durum, birincisinden çok daha verimlidir. Bu nedenle, işlev bağımsız değişkenin sahipliğini alırsa ve nesne türü verimli taşımayı destekliyorsa, değere göre pass değeri kullanılması önerilir .
Tarihsel bir not:
Aslında, herhangi bir modern derleyici, değerden geçerken pahalı olduğunu anlayabilmeli ve mümkünse bir const ref kullanmak için çağrıyı dolaylı olarak dönüştürebilmelidir.
Teoride. Pratikte, derleyiciler işlevin ikili arayüzünü bozmadan bunu her zaman değiştiremez. Bazı özel durumlarda (işlev satır içine alındığında), derleyici orijinal nesnenin işlevdeki eylemler yoluyla değiştirilmeyeceğini anlayabiliyorsa, kopya gerçekten kaldırılacaktır.
Ancak genel olarak derleyici bunu belirleyemez ve C ++ 'da hareket semantiğinin ortaya çıkışı bu optimizasyonu çok daha az alakalı hale getirdi.
1 Örn. Scott Meyers, Etkili C ++ .
2 Bu özellikle argüman alıp bunları dahili olarak inşa edilen nesnenin durumunun bir parçası olarak saklayabilen nesne yapıcılar için geçerlidir.