2011-05-10 111 views
0

我讀過一本關於C++中成員函數綁定問題的書。C++成員函數綁定

和它給下一個例子:

void Window::oops() { printf("Window oops\n"); } 
void TextWindow::oops() { 
printf("TextWindow oops %d\n", cursorLocation); 

Window  win; 
Window  *winPtr; 
TextWindow *txtWinPrt = new TextWindow; 
win = *txtWinPrt; 
winPtr = txtWinPtr; 
win.oops();  // executes Window version 
winPtr->oops(); // executes TextWindow or Window version; 

我不明白爲什麼會win.oops執行窗口的版本? win被定義爲Textwindow。

謝謝你的幫助。

+0

不,它被定義爲Window。 – 2011-05-10 11:51:41

+0

請添加類定義的繼承模式和使用virtual關鍵字可能會改變你的例子的行爲。 – VGE 2011-05-10 11:53:38

+0

看起來這不是一本很好的書。也許你可以找到另一個更有用的例子嗎? – 2011-05-10 11:55:30

回答

3

這是由slicing引起的。如果分配給超類的對象,那麼來自子類的信息將丟失。問題是這樣的語句:

win = *txtWinPrt; 

既然你指定一個子類(TextWindow)的目的是超一流(Window)的對象,這是不是在Window的的TextWindow所有信息都被切片了。

+0

@Hassan:我添加了一個解釋。更詳細的可以在我鏈接的優秀答案中找到。 – 2011-05-10 12:02:04

+0

非常感謝。它幫助到我。這本書用兩個字提到了切片,我不明白它的意思。 – Tom 2011-05-10 12:06:00

+0

切片與設計無關它是C++語義的物理副作用。在C++的所有其他特性(多重繼承)的背景下,尤其要把握這個概念。更合理的答案應儘可能增強理解。 – 2011-05-10 12:14:25

0
Window win 

是Window類的一個對象。它應該是用基類實例調用派生類方法的指針或引用。

0

使用面向對象(這就是你所要求的)動態多態性需要兩件事情。

  1. Window和Textwindow需要實現「is-a」關係。 (so,class TextWindow : public Window {});
  2. 爲了獲得運行時多態性,在基類中需要虛函數,如果自然找不到虛函數,通常是析構函數。虛函數會導致編譯器放下一個v表。

沒有這兩件事情,編譯器不會在調用函數中放置一個v表。 v表啓用運行時多態性,因爲函數調用是通過它進行的。

或者,你可以求助於c風格的函數指針,或類似boost :: bind的東西。但是這破壞了OO編程。我個人很少使用v-table。