关于虚函数的一些理解

经过多次试验,我发现虚函数应该是这个意思

对于任何一个类,无论是不是虚函数,所绑定的函数都是这个类里面的函数(这个叫做“隐藏”),比如下面的代码

class A
{
	public:
		void f()
		{
			cout<<1<<endl;
		}
		void g()
		{
			cout<<2<<endl;
		}
		virtual void h()
		{
			f(),g();
		}
};

在这个类里面,h()中的f()g()指的就是类A的f()g()

class B:public A
{
	public:
		void f()
		{
			cout<<3<<endl;
		}
		void g()
		{
			cout<<4<<endl;
		}
		void h()
		{
			f(),g();
		}
};

在这个类里面,h()中的f()g()指的就是类B的f()g()

那么如果我们在主函数中的代码如下:

int main()
{
	A *p=new B;
	p->h();
	return 0;
}

预期输出结果是3 4,而不是1 2。因为这里看起来是fg都不是虚函数了,应该调用类A的fg了,实际上并不是这样。由于我们的指针类型是A *,所以对于这一行代码p->h();,我们实际上调用的是A::h()(尽管这个指针指向的是类B对象),然而在我们发现A::h()是虚函数后,我们就考虑指针指向的对象,发现是类B对象,而这个类里面还有一个函数B::h(),于是我们重新调用B::h();而B::h()会调用B::f()B::g(),而我们发现这两者都不是虚函数,于是输出3 4

但是对于如下代码(在类B中加上了域解析符,并将f说明为虚函数):

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
class A
{
	public:
		virtual void f()
		{
			cout<<1<<endl;
		}
		void g()
		{
			cout<<2<<endl;
		}
		virtual void h()
		{
			f(),g();
		}
};
class B:public A
{
	public:
		void f()
		{
			cout<<3<<endl;
		}
		void g()
		{
			cout<<4<<endl;
		}
		void h()
		{
			A::f(),g();
		}
};
int main()
{
	A *p=new B;
	p->h();
	return 0;
}

输出是1 4,注意此时加了域解析符的函数一定采用静态绑定

再来看看下面的代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
class A
{
	public:
		virtual void f()
		{
			cout<<1<<endl;
		}
		void g()
		{
			cout<<2<<endl;
		}
		virtual void h()
		{
			f(),g();
		}
};
class B:public A
{
	public:
		void f()
		{
			cout<<3<<endl;
		}
		void g()
		{
			cout<<4<<endl;
		}
		void h()
		{
			f(),g();
		}
};
class C:public B
{
	public:
		void f()
		{
			cout<<5<<endl;
		}
		void g()
		{
			cout<<6<<endl;
		}
		void h()
		{
			f(),g();
		}
};
class D:public C
{
	public:
		void f()
		{
			cout<<7<<endl;
		}
		void g()
		{
			cout<<8<<endl;
		}
		void h()
		{
			f(),g();
		}
};
int main()
{
	B *p=new D;
	p->h();
	return 0;
}

首先p->h();这一行代码调用B::h(),然后发现B::h()是虚函数,于是考虑指向的对象,为类D对象,于是考虑D::h(),然后调用D::f(),发现为虚函数,在考虑对象,为类D对象,于是就是调用D::f(),对D::g()同理,于是输出7 8

书上课后习题的t5和t6可以再做一下,答案就存在本机的对应文件里面

posted @   最爱丁珰  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示