2011-02-04 41 views
17

kodum örnektir:Aşırı Yükleme operatörü Burada>

derleyici X Y'den operatöre> için "sorumluluk taşımak" için çalışıyor Neden
class X 
{ 
public: 
     void f() {} 
}; 

class Y : public X 
{ 
public: 
     X& operator->() { return *this; } 
     void f() {} 
}; 

int main() 
{ 
     Y t; 
     t.operator->().f(); // OK 
     t->f(); // error C2819: type 'X' does not have an overloaded member 'operator ->' 
       // error C2232: '->Y::f' : left operand has 'class' type, use '.' 
} 

? X :: op-> uyguladığım zaman, oraya X'i geri dönemezim - derleme hatası "sonsuz yineleme" yazarken X: op-> 'dan Z geri döndürür, yine Z'nin operatöre sahip olmadığını söyler. hiyerarşide daha yüksek.

Bu ilginç davranışı herkes açıklayabilir mi? :)

cevap

18

sorun operator -> bir işaretçi geri gerekiyordu, yani bir referans. Buradaki fikir, operator ->'un, işaretçiye uygulanmış olması gereken gerçek nesneye bir işaretçi döndürmesidir. Örneğin, bir aşırı operator -> bir sınıfa,

(myClass.operator->())->myValue; 

sizin koduyla sorun operator -> yüzden

myClass.operator->().f(); 

yazma, bir başvuru verir olmasıdır içine

myClass->myValue; 

çevirir kodu için kesinlikle yasal olduğundan, operatörü açıkça çağırıyorsunuz, ancak

yazıyorsunuz derleyici

myClass.operator->()->f(); 

bunu genişletmeye çalışıyor ve operator-> dönüş tipi bir işaretçi olmadığından

myClass->f(); 

, yasalara aykırıdır.

Bunu düzeltmek için , kodunuzu operator -> içinde bir işaretçi döndürecek şekilde değiştirin. Bir referansı döndürmek için bir operatöre aşırı yüklenmek isterseniz, operator *; işaretçi dereferences gerçekten referanslar oluşturmalıdır.

+9

ben 'operatöre>' sadece ihtiyaçlarını döndüren ne olursa olsun desteklemek için, bir işaretçi döndürür gerekendir söyleyemem. – GManNickG

+1

@ GMan- İyi nokta. Burada basitlik için gidiyordum ama sen haklısın. Bu tekniğe dayanan akıllı işaretçilerle çekebileceğiniz bazı eğlenceli oyunlar var. – templatetypedef

+0

@GMan: Bu tipler topluca * akıllı işaretçiler * olarak adlandırıldığı için, templatetypedef * pointer * teriminin kullanılmasının yanlış olduğunu düşünmüyorum, sadece genel anlamda kullanıyor. –

2

sözdizimi yanlış, olmalıdır:

T> T2

T2* T::operator ->();​ 

wikipedia makalesinin bak: Eğer aşırı istiyorsanız Operators in C and C++

, kullanmak gerekir aşırı yüklenen operatör için doğru sözdizimi

19

Çünkü bu nasıl olur? -> adında C++ çalışmaktadır.

Aşırı yüklenmiş ->'u kullandığınızda, a->b ifadesi a.operator->()->b'a çevrilir. Bu, aşırı yüklenen operatörünüzün ->'un, operatörün başka bir uygulamasını destekleyecek bir şey döndürmesi gerektiği anlamına gelir ->. Bu nedenle, aşırı yüklenen ->'un tek bir çağrısı, zincire son veren -> dahili bir uygulamaya ulaşana kadar aşırı yüklenmiş -> s uzun bir zincirleme zincirine dönüşebilir.

Sizin durumunuzda 'u, X& değil, aşırı yüklenmiş ->'dan döndürmeniz gerekir.

1

Muhtemelen istiyorum:

class Y : public X 
{ 
public: 
     X* operator->() { return this; } 
     void f() {} 
}; 
İlgili konular