Jer*_*ten 9 c++ oop polymorphism
以下是http://www.cplusplus.com/doc/tutorial/polymorphism.html(为便于阅读而编辑)的多态性示例:
// abstract base class
#include <iostream>
using namespace std;
class Polygon {
protected:
int width;
int height;
public:
void set_values(int a, int b) { width = a; height = b; }
virtual int area(void) =0;
};
class Rectangle: public Polygon {
public:
int area(void) { return width * height; }
};
class Triangle: public Polygon {
public:
int area(void) { return width * height / 2; }
};
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = ▭
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl; // outputs 20
cout << ppoly2->area() << endl; // outputs 10
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是编译器如何知道ppoly1是一个Rectangle而ppoly2是一个三角形,以便它可以调用正确的area()函数?它可以通过查看"Polygon*ppoly1 =▭"行并知道rect是一个Rectangle来找到它,但是在所有情况下都无法工作,不是吗?如果你这样做了怎么办?
cout << ((Polygon *)0x12345678)->area() << endl;
Run Code Online (Sandbox Code Playgroud)
假设您被允许访问该随机内存区域.
我会测试一下,但我现在无法在计算机上测试.
(我希望我不会错过任何明显的东西......)
Chr*_*ung 24
每个对象(属于具有至少一个虚函数的类)都有一个名为a的指针vptr.它指向vtbl其实际类(每个具有虚函数的类至少有一个;对于某些多重继承方案,可能不止一个).
它vtbl包含一堆指针,每个虚拟函数一个.所以在运行时,代码只是使用对象vptr来定位vtbl,并从那里找到实际被覆盖函数的地址.
在特定情况下,Polygon,Rectangle,和Triangle每个人都有一个vtbl,每一个条目指向其相关area方法.你ppoly1将有vptr指向Rectangle的vtbl,并ppoly2同样用Triangle的vtbl.希望这可以帮助!
Chris Jester-Young给出了这个问题的基本答案.
维基百科有更深入的处理.
如果你想知道这类事物是如何工作的全部细节(以及所有类型的继承,包括多重和虚拟继承),最好的资源之一是Stan Lippman的" Inside the C++ Object Model ".