当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C++编译器如何知道要调用哪个虚函数实现?》经验,为你挑选了2个好方法。

以下是http://www.cplusplus.com/doc/tutorial/polymorphism.html(为便于阅读而编辑)的多态性示例:

// abstract base class
#include 
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;
}

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

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

假设您被允许访问该随机内存区域.

我会测试一下,但我现在无法在计算机上测试.

(我希望我不会错过任何明显的东西......)



1> Chris Jester..:

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

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

在特定情况下,Polygon,Rectangle,和Triangle每个人都有一个vtbl,每一个条目指向其相关area方法.你ppoly1将有vptr指向Rectanglevtbl,并ppoly2同样用Trianglevtbl.希望这可以帮助!



2> Michael Burr..:

Chris Jester-Young给出了这个问题的基本答案.

维基百科有更深入的处理.

如果你想知道这类事物是如何工作的全部细节(以及所有类型的继承,包括多重和虚拟继承),最好的资源之一是Stan Lippman的" Inside the C++ Object Model ".

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有