关于虚函数的一些理解
经过多次试验,我发现虚函数应该是这个意思
对于任何一个类,无论是不是虚函数,所绑定的函数都是这个类里面的函数(这个叫做“隐藏”),比如下面的代码
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
。因为这里看起来是f
和g
都不是虚函数了,应该调用类A的f
和g
了,实际上并不是这样。由于我们的指针类型是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可以再做一下,答案就存在本机的对应文件里面
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构