我对vtable内容的困惑

时间:2015-08-04 13:22:19

标签: c++

在下面的代码中,不允许使用语句“aptr-> fun2()。”我的疑问是: -

1.派生类vtable的内容是什么。 2.如果base vptr访问派生类vtable,如果它包含函数fun2(),那么为什么不允许aptr-> fun2()。

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class A
{
public:
    virtual void fun1();            
};

void A::fun1()
{
    cout << "\n Class A fun1 function called. ";
}

class B : public A
{
public:
    virtual void fun1();
    virtual void fun2();  
};

void B::fun1()
{
    cout << "\n Class B fun1 function called";
}

void B::fun2()
{
    cout << "\n Class B fun2 function called";
}

int _tmain(int argc, _TCHAR* argv[])
{
    A* aptr =new B();
    aptr->fun1();
    aptr->fun2();//cannot be called
    _getch();
    return 0;
}

2 个答案:

答案 0 :(得分:2)

您无法使用fun2致电aptr,因为这是A*,您必须先投出

static_cast<B*>(aptr)->fun2();

virtual函数fun1将处理从B::fun1调用重载的aptr,但这并不意味着您可以访问特定于B的方法没有铸造。

答案 1 :(得分:2)

A未定义函数fun2(),因此无法通过指向A的指针访问它。你在代码中表达的是:

我有一个A,可以fun1()。我有B A,但除此之外还可以fun2()

但仅仅因为你的B可以做fun2(),其他任何A都无法做到这一点。如果您的目标实际上是可能的,那么{{1} } s必须能够A。这里可以放弃,但你应该重新考虑你的设计。您尝试使用fun2()但某些A需要与其他{{}}}不同的处理的事实违反了Liskov Substitution Principle