2012-10-03 24 views
11

Bir operatöre aynı parametre listesiyle iki kez aşırı yükleniyorum. ancak farklı dönüş türüyle:C++ aşırı yük operatörü iki kez, bir const olmayan const başvuru ve diğer const referansı, tercih nedir?

T& operator()(par_list){blablabla}  
const T& operator()(par_list){blablabla} 

yüzden neyin tercihi veya durumuna göre aranmak function() operatörü, aradığım zaman? Const işlevini çağırırsam() çağrısı T & one olmalıdır.

Sadece C++ ile böyle bir durumun nasıl işlediğini ve varsayılan tercihin nasıl çalıştığını merak ediyorum.

Teşekkür

+1

terimdir * aşırı yük *, hem hayır. – chris

+2

C++ Dönüş türüne göre aşırı yüklenmeye izin vermez. Biri yapabildiği/yapması gereken şeylere gidebilir, ama önemli değil. Bir hile, geri dönüş tipi olduğu zaman, yöntem yüklenmesini yapmaktır, çünkü aşırı yüklenebilir. Bellemim const yöntemi tercih edilir, const olmayan çağrının çağrılması yasal olmaz. – Joe

cevap

21

Bu işlevler birbirini aşırı yüklemez; Aynı imzalara sahipler ve aynı işlevi yeniden tanımlama girişimi, bu bir hatadır. Dönüş tipi, bir fonksiyonun imzasının bir parçası değildir. Bir işlevi aşırı yüklemek için, aynı ada sahip ikinci bir işlev, ancak farklı parametreler veya const/volatile niteleyicileri bildirmeniz gerekir - yani, işlevdeki niteleyiciler, dönüş türünü değil.

(Bunlar birbirlerini de geçersiz kılmazlar; geçersiz kılan sınıflar, temel sınıfların sanal işlevlerine göre türetilmiş sınıfların ne yaptığını geçersiz kılar).

Bir üye işlevinin bir const ve const bir aşırı yük tanımlaması yaygındır;

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 
           ^^^^^ 
Şimdi

dışı bir const nesneye () uygularsanız adı verilecek ilk ve const nesne üzerinde ikinci: const aşırı yük değil, sadece döndürme türü, işlevi const bildirmelidir. Örneğin,

Thingy nc; 
Thingy const c; 

nc(); // calls the first (non-const) overload 
c(); // calls the second (const) overload 
+0

@ DavidRodríguez-dribeas: Tamam, "imzanın" dahil edilen dönüş türünü fark etmedim. "Hangi aşırı yüklenmeyi belirleyen bitler" için resmi bir terim var mı? –

+0

@ DavidRodríguez-dribeas Belki de bunu açıklığa kavuşturabilirsiniz çünkü C++ 03'ten beri değişmiş gibi görünüyor. §1.3.18’in şablon işlevlerine başvurduğu görülmektedir. Ancak, şablonsuz (ücretsiz veya üye) işlevler için girdiler dönüş değerlerinden bahsetmez. Şablon işlevi uzmanlıklarına yönelik girişler de yoktur. – juanchopanza

+0

@juanchopanza: Siz haklısınız, yorumu kaldırarak. Mike, standardın dikkatli bir şekilde tekrarlanmasını, fonksiyon şablonlarında (Juancho'dan bahseder) dönüş türünün imzanın bir parçası olduğunu gösterir. Düzenli işlevler için imza, dönüş türünü içermez. C++ 03'in bir dipnotu vardır: * İşlev imzaları geri dönüş türünü içermez, çünkü bu aşırı yüklenme çözünürlüğüne katılmaz. * Cevabın karışıklığı için üzgünüm :) –

3

Sen dönüş türüne göre bir fonksiyon/aşırı yükleme yapamazsınız. Derleyicinin burada bir hata atmasını beklerdim. Ne yapabilirsiniz

const T& operator()(par_list) const {blahblah} 

sadece bu const alıcı üzerindeki çağrılabilir anlamına const tanımlamasını kullanarak, bir const yöntem olarak yöntem kendisi belirtmek olduğunu, ama aynı zamanda aşırı yük çözünürlükte kullanılır. Bu, yönteme iletilen örtülü *this parametresini etkilediği için olur; const yöntemi, *this üzerinde const niteleyicisini kullanır ve aşırı yükleme çözünürlüğü sırasında const niteleyicileri dikkate alınır.

1

Operatörlerinizi tanımlama şekliniz, derleyicinin hangi operatörü() çağırması gerektiğine karar veremez. Fonksiyonların (ve operatörlerin) aşırı yüklenmesi sadece argüman türünde, asla dönüş tipinde yapılamaz. Ve aslında, ikincisini tanımladığınız anda derlemede bir hata olacak, derleyici aynı işlevi/operatörü yeniden tanımladığınızı düşünüyor.

Ancak, aşağıdaki (ne varsa ve muhtemelen) yaygındır:

Eğer üye fonksiyonları ve üye fonksiyonları statik olmayan tanımlayan çünkü argüman listesinden sonra bu ek "const" var
T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 

örtük var gizli argüman: sınıfın örneğine "bu" işaretçi. Buradaki "const" anahtar sözcüğü, bu gizli göstericinin bir const örneğinin olup olmadığını gösterir.Bu argüman aşırı yüklenme çözünürlüğüne katılır ve bu durumda derleyicinin hangi operatörün kullanacağını seçmek için kullandığı durumdur.

Yani:

class A { 
    T& operator()() { ... } 
    const T& operator()() const { .... } 
}; 

A a; 
const A& ca(a); 
a(); -> returns a T& 
ca(); -> returns a const T& 
İlgili konular