为什么使用虚拟表而不是函数指针? 我是C++初学者,我不明白为什么C++使用虚拟表来实现多态而不是简单的函数指针。 让我们考虑一个例子: struct Shape { virtual double area() = 0; }; struct Square: public Shape { virtual double area(); /* ... */ }; struct Circle: public Shape { virtual double area(); /* ... */ }; double f(Shape &s) { return 42.0 + s.area(); } < C++如何通常(总是?)实现多态性:形状< /> >,并且每个派生类都有隐藏的指针作为第一个元素。调用s.area()时,指向相应area函数的指针取自s的虚拟表 但是如果我不知道C++和虚拟表,想在C中实现这样的多态性,我会这样做: struct Shape { double (*area)(struct Shape *this); }; struct Square { /* is a Shape */ double (*area)(struct Square *this); /* ... */ }; struct Circle { /* is a Shape */ double (*area)(struct Circle *this); /* ... */ }; double f(struct Shape *s) { return 42.0 + s->area(s); } double cirlce_area(struct Circle *this); double square_area(struct Square *this); /* ... */ struct Circle c = { &circle_area, ... }; printf("%f", f((struct Shape *)c));

为什么使用虚拟表而不是函数指针? 我是C++初学者,我不明白为什么C++使用虚拟表来实现多态而不是简单的函数指针。 让我们考虑一个例子: struct Shape { virtual double area() = 0; }; struct Square: public Shape { virtual double area(); /* ... */ }; struct Circle: public Shape { virtual double area(); /* ... */ }; double f(Shape &s) { return 42.0 + s.area(); } < C++如何通常(总是?)实现多态性:形状< /> >,并且每个派生类都有隐藏的指针作为第一个元素。调用s.area()时,指向相应area函数的指针取自s的虚拟表 但是如果我不知道C++和虚拟表,想在C中实现这样的多态性,我会这样做: struct Shape { double (*area)(struct Shape *this); }; struct Square { /* is a Shape */ double (*area)(struct Square *this); /* ... */ }; struct Circle { /* is a Shape */ double (*area)(struct Circle *this); /* ... */ }; double f(struct Shape *s) { return 42.0 + s->area(s); } double cirlce_area(struct Circle *this); double square_area(struct Square *this); /* ... */ struct Circle c = { &circle_area, ... }; printf("%f", f((struct Shape *)c));,c++,polymorphism,virtual-functions,C++,Polymorphism,Virtual Functions,调用s->area()时,将使用s结构中的第一个指针 为什么C++使用虚拟表而不是将指针放置在结构的开始时的虚拟函数(以相同的顺序)?我目前找不到最后一种方法不起作用的任何原因。从概念上讲,这是完全一样的 虚方法表只是一个函数指针列表。它不集成在对象本身中,因为它对于对象的类是静态的,所以它可以在同一类的实例之间共享(在初始化期间节省计算能力,在对象的整个生命周期内节省内存) 在C++中,每个构造函数将虚拟方法表指针设置为它所属的类的指针。因此,在最外层的构造函数运行之后,虚拟方法将解析为对象所

调用
s->area()
时,将使用
s
结构中的第一个指针


为什么C++使用虚拟表而不是将指针放置在结构的开始时的虚拟函数(以相同的顺序)?我目前找不到最后一种方法不起作用的任何原因。

从概念上讲,这是完全一样的

虚方法表只是一个函数指针列表。它不集成在对象本身中,因为它对于对象的类是静态的,所以它可以在同一类的实例之间共享(在初始化期间节省计算能力,在对象的整个生命周期内节省内存)


<>在C++中,每个构造函数将虚拟方法表指针设置为它所属的类的指针。因此,在最外层的构造函数运行之后,虚拟方法将解析为对象所在的类。

考虑包含许多虚拟方法的类会发生什么:您将不得不为每个实例分别存储X个函数指针。这很快就会变得非常浪费


使用vptr还可以帮助实现其他语言功能:很容易使用vptr的值来确定对象的运行时类型(想想
typeid
)。

那么每个对象都必须包含一个函数指针数组,对于所有实例,使用单一共享副本。注意C++标准不需要使用指针到虚拟表。实现也可以使用哈希表,或者像您刚才那样在对象中直接放置函数指针。即使在C语言中,您也可以将它们都放在不同的结构中,并只保留指向该结构的指针。事实上,这在Linux内核中是非常惯用的。不仅仅是Linux内核,微软COM也做同样的事情。但我想更令人惊讶的是Linux考虑到Linux不喜欢C++,所以使用了这样一种普通的C++模式。