如果我有基类:
struct Base
{
void foo()
{
bar();
}
virtual void bar()
{
}
};
派生类:
struct Derived : public Base
{
void bar()
{
cerr << "Derived here\n";
}
};
编写此代码时会发生这种情况:
Derived d;
d.foo();
我会看到打印“Derived here” - 自Derived::bar
被调用。但我没有通过指针调用base,而是在这里工作的多态。为什么?是因为bar
中对Base::foo
的调用实际上隐含于this->bar()
,bar
是否在类的vtable中找到了?
答案 0 :(得分:4)
你的猜测是完全正确的(尽管请记住C ++标准对vtable没有任何意义)。
答案 1 :(得分:1)
是不是因为在Base :: foo中对bar的调用实际上隐含于this-&gt; bar()并且bar在类的vtable中找到了?
d.foo()
调用实际上是(&d)->foo()
,因此foo()
会收到this
指针,查找vtable,并找到正确的bar()
实现。< / p>
换句话说,对于foo()
,无论是否通过指针调用它都无关紧要。无论如何,它总是得到一个this
指针并以相同的方式工作。
答案 2 :(得分:0)
你是对的。它不是一个显式指针,但它确实在vtable中查找该函数的第一个条目。由于派生类为该函数提供了一个新条目,因此您正在调用派生函数。无论指针如何,多态性都可以工作 - 只是所有的例子都使用指针来表明使用多态解耦是多么容易。
答案 3 :(得分:0)
1)为什么要在结构中定义方法?
2)是的,多态性是让你调用Derived::foo()
而不是Base::foo()
的原因,因为你宣称它是虚拟的。实际上,这允许代码在类的vtable中找到正确的方法(或者编译器为您创建的指针表结构,以跟踪多态方法。)