2011-02-07 62 views
6

可能重複:
Overloading operator ->操作員 - >「鏈接」指針?

嗨,

我見過operator->()被鏈接(再使用)其被評估之後,例如:

struct Bar 
{ 
    Bar() : m_str("Hello world!") {} 
    const string* operator->() const { return &m_str; } 
    string m_str; 
}; 

struct Foo 
{ 
    const Bar& operator->() const { return m_bar; } 
    Bar m_bar; 
}; 

int main() 
{ 
    Foo f; 
    cout << f->c_str() << endl; 
    return 0; 
} 

工作得很好,這需要三個operator->()進行評估 - Foo::operator->(),Bar::operator->()和正常的指針分辨率。

但它不會在指針中間工作 - 如果Foo::operator->()返回指向Bar而不是引用的指針,它不會編譯。例如,auto_ptr<auto_ptr<string>>也是如此。

是否特定於非超載operator->()因此它只應用一次而不會導致鏈接? 是否有可能在不使用(*ptr2)-> ...的情況下使代碼在工作之下?

int main() 
{ 
    string s = "Hello world"; 
    auto_ptr<string> ptr1(&s); 
    auto_ptr<auto_ptr<string> > ptr2(&ptr1); 
    cout << ptr1->c_str() << endl; // fine 
    cout << ptr2->c_str() << endl; // breaks compilation 
} 

謝謝!

+0

重載[重載運算符 - >](http://stackoverflow.com/questions/4896238/overloading-operator)[AndreyT的答案解釋了`operator->`的行爲以及如何發生「鏈接」。] – 2011-02-07 15:48:36

+1

@詹姆斯我贊成保持開放,因爲問題的措辭是不同的。它可以幫助其他人找到答案。 – 2011-02-07 15:52:49

回答

12

C++ 98標準§13.5.6/ 1「類的成員訪問」:

表達式x->m被解釋爲對(x.operator->())->m如果T存在T::operator->類型的類對象x和如果操作者是通過重載解析機制(13.3)在最佳匹配功能中選擇。

這意味着在實踐中,當x是一個指針,你不’噸得到鏈接;您只需獲得內置的operator->(即x->mx指針轉換爲(*x).m)。

但是當x是類型爲T的對象時,則可以獲得鏈接效果。因爲那麼解釋爲(x.operator->())->m可以是(x.operator->())本身是某個類的對象,說類U。那麼第二個->可以解析爲U::operator->等等,如果這個結果再次是一個類類型的對象...... hellip;

像你的情況一樣,Foo::operator->產生(引用)類Bar的一個對象,它確實定義了一個operator->

但是,當operator->返回指針時,例如, std::auto_ptr<T>::operator->呢,那就是使用的內置operator->

順便說一下,鏈接可以用實際上防止某人不恰當地使用deletestd::auto_ptr不這樣做。我從來沒有見過它完成。

但是在[comp.lang.C++。moderated]中曾經有一段長篇討論,關於如何防止由智能指針管理的原始指針的無意delete,這是討論的一種可能性。

乾杯& hth。

0

不,它不可能工作。如果您可以爲string *重載operator ->,則可以使其工作。但operator ->已經有了所有指針類型的定義。所以,就像你不能爲原始數字類型重載+一樣,你不能爲任何指針類型重載operator ->

即使可以,編譯器如何知道遞歸何時結束?

3

你的第一個例子工作的原因是你返回了一個引用而不是指針。除非超載,否則該運算符通常無效。因此,編譯器必須在鏈中執行重載函數。但是,在auto_ptr的情況下,您實際上會返回一個實際指針,並且會爲常規指針調用缺省值operator ->

有關更多詳細信息,請參閱Overloading operator ->問題。