1
9
标准没有留下直接调用b::foo的开口,并且避免了表查找:
输出:
所以你可以得到你所期望的行为,如下所示:
现在打电话的人应该用酒吧代替foo。如果他们有一个c*,那么他们可以将其强制转换为a*,在这种情况下
不过,我不知道什么时候会有人想要这种行为。虚拟函数的关键是为给定的对象调用相同的函数,不管您使用的是什么基或派生类指针。因此,C++假定如果通过基类对特定成员函数的调用是虚的,那么通过派生类调用也应该是虚的。 |
2
6
当你宣布
|
3
5
仅仅因为类被强制使用vtable,并不意味着编译器被强制使用它。如果对象的类型是静态的,编译器可以作为优化绕过vtable。例如,在这种情况下,可能会直接调用b::foo:
不幸的是,我知道验证这一点的唯一方法是查看生成的程序集代码。 |
4
2
因为从技术上讲,无论你做什么,它都是虚拟的,它在表格中占有一席之地。其余的将是一个语法执法,这是C++与Java不同的地方。 |
5
1
定义第一个虚拟函数时,将为基类创建vtable。在示例中,foo()在vtable中有一个条目。当派生类从基类继承时,它也继承vtable。派生类在其vtable中必须有一个foo()的条目,这样当派生类通过基类指针以多态方式引用时,调用将被适当地重定向。 |
6
0
似乎至少Visual Studio能够利用
为生成相同的代码
鉴于没有
不过,我不知道其他编译器是否也这么做。 |
Brendan · Java中从父类继承的对象的ArrayList 2 年前 |
Tali · 继承-您应该使用基类,还是它们只是子类的框架? 2 年前 |
mask2 · 如何轻松访问继承类的功能? 2 年前 |
Dimon · 父类中的Setter,以及一些没有参数的子类 2 年前 |
Miguerurso · Javascript类继承无法正常工作 2 年前 |
GuessMe · 返回新类对象的正确方法(也可以扩展) 2 年前 |
Daniel Lizik · 重写父类构造函数的子类成员初始值设定项 2 年前 |
i_know_what · 以基类作为参数重写错误的方法 2 年前 |