2011-05-10 130 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。