关于虚函数的一点问题
虚函数的一些大致都了解了,关于父类指向子类有点疑问。
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
class Derive : public Base{
public:
virtual void f() { cout << "Derive::f" << endl; }
virtual void g1() { cout << "Derive::g1" << endl; }
};
Derive继承了Base,覆盖了函数f,那么在调用的经常会有
Base *b = new Derive();
b->f();
这里b应该是调用了Derive中的f(),输出就是Derive::f
然后如果我b->g1();就会报错
我的疑问就是在Base *b = new Derive();这里,
新建了Derive类的,用父类Base指向了它,事实准确的说应该是指向了Derive的虚函数表,因为虚函数表是在对象的最前位置(这么理解对不对?)
Derive的虚函数的排列顺序是 B:f(),B:g(),B:h(),D:g1()。
那么显然指针指向这个表时,前三个虚函数可以调用是没有问题的,最后一个D:g1()不能调用,能解释下吗?
[解决办法]
g1还是g?
我要先确定一下,你是否存在拼写错误。
如果不是拼写问题。
那么g1是只存在派生类中,并不在基类中,于是在这两个类的关系中,g1和重写没关系啊。
[解决办法]
g1是存在的,但是编译器不知道这一点。比如说你强转一下类型为子类就能用了,也不会出错,虽然日常工作不可能有这样的需求。
[解决办法]
标准不要求虚函数表存在,更没要求一定要在对象最前端,虽然 VS 系列编译器倾向于这么做,另外虚继承多重继承一上来,虚表在哪里都有可能。最好的理解就是 g1 非 Base 成员,调用失败,不要试图从编译器细节猜测标准。
[解决办法]
哥们,你确定你明白虚函数?
[解决办法]
那么Base *b = new Derive();指向了哪里呢?
就是父类的指针,指向了一个子类对象。跟虚函数表没什么直接的关系,不要被自以为是误导。
就LZ列出的类,虽然我没有深入研究过虚函数表,但是我详细,逻辑上有两张虚函数表:
第一个是所有基于Base的虚函数表,有f,g,h三个函数;
第二个是所有基于Drived的虚函数表,有g1函数。
父类的指针,指向了一个子类对象,这时只能查到f,g,h的虚函数表。
