加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C编译器如何知道要调用的虚拟函数的哪个实现?

发布时间:2020-12-16 03:13:10 所属栏目:百科 来源:网络整理
导读:以下是 http://www.cplusplus.com/doc/tutorial/polymorphism.html的多态性示例(可编辑性): // abstract base class#include iostreamusing namespace std;class Polygon { protected: int width; int height; public: void set_values(int a,int b) { widt
以下是 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 = &rect;
    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;
}

我的问题是编译器如何知道ppoly1是一个Rectangle,ppoly2是一个三角形,以便它可以调用正确的area()函数?可以通过查看“Polygon * ppoly1 =& rect”来找到它并且知道rect是一个Rectangle,但是在所有情况下都不行,是吗?如果你做了这样的事情怎么办?

cout << ((Polygon *)0x12345678)->area() << endl;

假设你被允许访问那个随机的内存区域.

我会测试一下,但我现在不能在电脑上.

(我希望我没有缺少明显的东西…)

解决方法

每个对象(属于具有至少一个虚拟函数的类)具有一个称为vptr的指针.它指向其实际类的vtbl(每个具有虚函数的类具有至少一个类,对于某些多重继承方案可能有一个以上).

vtbl包含一堆指针,每个指针一个用于每个虚拟函数.所以在运行时,代码只是使用对象的vptr来定位vtbl,并从那里实际覆盖的函数的地址.

在具体情况下,多边形,矩形和三角形都有一个vtbl,每个都有一个条目指向其相关的区域方法.您的ppoly1将有一个指向Rectangle的vtbl的vptr,ppoly2与Triangle的vtbl类似.希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读