在此代码中:
void Window::oops() { printf("Window oops\n"); }
void TextWindow::oops() {
printf("TextWindow oops %d\n", cursorLocation);
}
TextWindow x;
Window a;
Window *b;
TextWindow *c;
a = x; a.oops(); // executes Window version
b = &x; b->oops(); // executes TextWindow or Window version
c = &x; c->oops(); // executes TextWindow version
b = &x; b->oops();
执行TextWindow 或窗口版本意味着什么?怎么决定?
答案 0 :(得分:4)
如果oops()
是虚拟的,则b->oops()
来电将使用TextWindow
版本。如果不是,则使用Window
版本。
答案 1 :(得分:1)
虽然没有具体说明,但我假设TextWindow
来自Window
(直接或间接)。
在这种情况下,基本问题是oops()
是否是虚拟成员函数。
如果oops()
是虚拟的,则通过指针或引用进行的调用基于 dynamic 类型 - 指针/引用实际引用的对象的类型。 / p>
如果oops()
不是虚拟的,则通过指针或引用进行的调用基于 static 类型 - 指针定义为指向的对象类型,无论它实际指向的对象类型。
struct Window {
void oops() { std::cout << "Window::oops()\n"; }
virtual void oops2() { std::cout << "Window::oops2()\n"; }
};
struct TextWindow : Window {
void oops() { std::cout << "TextWindow::oops()\n"; }
virtual void oops2() { std::cout << "TextWindow::oops2()\n"; }
};
int main() {
Window w;
w.oops(); // Both of these print "Window::...".
w.oops2();
TextWindow tw;
tw.oops(); // Both of these print "TextWindow::...".
tw.oops2();
Window &w2 = tw;
w2.oops(); // oops() is not virtual, and we're using a reference to a Window,
// so this invokes Window::oops().
w2.oops2(); // oops2() is virtual, so even though w2 is a reference to a
// Window, this invokes TextWindow::oops2(), because the reference
// refers to the object tw, which is a TextWindow.
return 0;
}
答案 2 :(得分:0)
a = x; a.oops(); // executes Window version
这个导致对象切片。请参阅此wiki条目:Object slicing
b = &x; b->oops(); // executes TextWindow or Window version
使用它,您可以多态调用虚函数。它将调用TexTWindow文章,而不是Window版本!
c = &x; c->oops(); // executes TextWindow version
它只使用相同类型的指针调用虚函数作为对象的动态类型,在本例中为TextWindow
。
答案 3 :(得分:0)
这是基本的polymorphism:
b是指向Window的指针,它可以指向Window对象或从Window继承的类型的对象。然后,继承的类型可以重新实现oops()函数(如果在Window定义中将oops()指定为虚拟)。
为了实现这一点,c ++编译器将添加额外的信息以在对象数据中路由函数调用,几乎总是以v-table的形式。
允许你操作一组Windows,调用基本成员函数,不要担心对象最终会做什么。然后,该对象可以以特定的方式为其特定的子类型实现函数。
请参阅维基百科页面中的简单示例:http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming