2011-06-05 64 views
9

這只是一個實驗代碼。過載虛擬操作符 - >()

struct B 
{ 
    virtual B* operator ->() { return this; } 
    void foo() {} // edit: intentionally NOT virtual 
}; 

struct D : B 
{ 
    virtual D* operator ->() { return this; } 
    void foo() {} 
}; 

int main() 
{ 
    B &pB = *new D; 
    pB->foo(); // calls B::foo() ! 
} 

我知道operator必須使用對象或引用來調用;因此在上述情況下確實參考pB仍堅決B的目標? 雖然這是不實際的,但出於好奇,有沒有辦法通過pB調用D::operator ->

+0

當你想有富()虛擬無厘頭有操作符 - >虛擬。 – 2011-06-05 03:55:18

+0

我可能會在這裏丟失一些東西,但是隻是使'void foo()'虛擬有什麼問題呢?在這種情況下'operator - >()'是完全沒有意義的,尤其是因爲它只是返回'this'。 – 2011-06-05 03:56:32

+0

@In silico,我同意,這只是一個實驗代碼,用於瞭解'operator - >'變成'virtual'時會發生什麼。我編輯了我的問題。謝謝。 – iammilind 2011-06-05 04:07:37

回答

8

我認爲這是調用D::operator->,但返回值被視爲B*,所以B::foo()被調用。

這是如何協變返回類型行爲的神器。

1

它調用哪個操作符(在這種情況下可能是D::operator->)並不重要,重要的是this。在這種情況下,this指針是B*類型的,所以foo呼叫被解除引用到B::foo。如果是virtual - 它會正常工作,但你故意沒能virtual ...

+0

+1,它絕對是'D :: operator->'(不大可能)。 – iammilind 2011-06-05 04:35:08

2

pBB&類型。因此調用它的任何方法(如operator->)將在B得到簽名,因此pB.operator->()將返回一個B*。當然,因爲它是虛擬的,所以使用D中的實際實現。重要的是返回類型是由pB變量的類型定義的。

因此,我們的operator->已返回B*,因此調用foo()與其他B*一樣繼續。

+0

這個答案並不新鮮,但我認爲它可能會有助於嘗試在邏輯上進一步擴展。 – 2011-06-05 05:15:50

1

根據調用中使用的對象的動態類型調用虛擬成員函數。非虛擬成員函數根據調用中使用的對象的類型靜態調用。

功能foo不虛。這意味着它總是按照靜態對象的類型進行調用。在這種情況下,靜態類型是B(因爲B::operator ->結果的聲明類型爲B *),所以B::foo被調用。