首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++中虚函数的原理

C++中虚函数的原理
EN

Stack Overflow用户
提问于 2013-07-16 08:18:29
回答 1查看 382关注 0票数 5

我是C++的新手,我刚刚学习了虚拟函数。

我听说当我定义一个虚函数时,编译器会生成一个vtable,其中包含类的虚函数地址。当调用虚函数时,编译器使用vtable查找其地址。

我真的不能理解为什么编译器没有调用对象所属的类实例的函数。

为什么编译器使用vtable?你能解释一下这个吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-16 08:30:25

我真的不能理解为什么编译器没有调用一个类实例的函数?

这就是编译器所做的--确保你的程序调用实例所属类的函数。这里的关键字是实例:实例的类的知识在编译时不可用。

考虑这个简单的例子:

代码语言:javascript
复制
struct Dude {
    virtual void howdy() = 0;
};
struct Bob : public Dude {
    virtual void howdy() { cout << "Hi, Bob!" << endl; }
};
struct Moe : public Dude {
    virtual void howdy() { cout << "Hi, Moe!" << endl; }
};
// Note the pass by reference below: passing by reference or by pointer,
// but not by value, is important for achieving polymorphic behavior.
void say_hi(Dude& dude) {
    dude.howdy(); // <<== Here is the tricky line
}
int main(int argc, char* argv[]) {
    Bob b;
    Moe m;
    Dude *d = rand() & 1 ? (Dude*)&b : &m;
    say_hi(*d);
}

注意棘手的一行:编译器有实例,但它不知道类。实际上,它有点了解类,但不是最具体的类。编译器在编译时拥有的知识足以知道有一个名为howdy的函数,但不足以决定在运行时调用几种可能性中的哪一种。

这就是vtable的用武之地:编译器知道Dude的子类将有一个指向它们的howdy函数的指针嵌入到它们的vtable中。这就是他们在编译时需要知道的全部内容!它们插入一个在运行时查找函数指针的虚拟调用,实现您期望的行为(这种行为的奇妙说法是“多态性”)。这是一个在ideone上运行的demo of this program

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17666029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档