请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

面试碰到有关非继承情况下虚函数的问题,希望老师解惑

#include <iostream>

using namespace std;

class A {

public:
	void f1() {
		printf("A::f1");
	}

	virtual void f2() {
		printf("A::f2");
	}
};

class B {

public:
	virtual void f1() {
		printf("B::f1");
	}

	virtual void f2() {
		printf("B::f2");
	}
};

int main() {
	B object;
	A* p = (A*)&object;
	
	p->f1();
	p->f2();

	return 0;
}

老师您好,面试的时候碰到这样的问题,以前碰到的都是继承情况下的虚函数用法,这种非继承情况下的虚函数用法没遇见过,我的理解是
1.非虚函数不使用虚函数表,调用位置是固定的,所以p->f1();输出"A::f1"
2.面试时候,我猜的是,A* p = (A*)&object;这个操作应该类似于A类继承了B类,而A类重写了虚函数f2,所以输出是"A::f2"
当时面试官说,你没有理解C++的真谛和精髓
后来我又想了想,感觉这应该是一种未定义行为,毕竟虚函数在设计上就是保证派生类能调用重写方法,这样的话输出可以会根据环境的不同而变化
面试完,我运行了一下发现输出是"A::f1"“B::f1”,试了下不同的环境都是这样的输出,不清楚为什么p->f2()输出的是"B::f1",希望老师解惑,谢谢

正在回答

1回答

观点点在于虚表结构的填充的顺序,建议你好好调试下虚表的结构,多试几种情况。咋们一期课程中关于C++对象模型和虚表讲得比较粗浅,打算二期在这方面会更仔细得分析一下。

0 回复 有任何疑惑可以回复我~
  • 提问者 12345ayu #1
    好的,谢谢老师
    回复 有任何疑惑可以回复我~ 2020-08-12 10:55:57
  • 老师有空的话能帮忙讲解一下上面这段代码为啥输出是"A::f1"“B::f1"吗?
    回复 有任何疑惑可以回复我~ 2021-11-09 20:14:28
  • 佐岸2 回复 嘤嘤鸣 #3
    A* p = (A*)&object 这句代码 说明 A类型的指针 指向了B 虚函数表中的f1函数指针。所以当p->f2是 发生了动态绑定,调用了B中的f1虚函数。而p->f1() 由于A中的f1是普通函数,直接调用指针对应的那个函数。
    回复 有任何疑惑可以回复我~ 2021-11-12 10:30:27
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信