C++虚函数汇总

不打扰是莪最后的温柔 提交于 2020-02-16 19:03:44

关于C++虚函数,主要是服务于多态,但里面一些细节的点还是很多的,我总结一下我目前所遇到的基本重要的几点,通过一下几个方面讲解:

  • 虚函数的介绍
  • 那些函数可以设为虚函数?那些函数不行?
  • 纯虚函数

虚函数的介绍:

虚函数说白了就是成员函数前加上virtual,虚函数主要实现多态,对多态访问父类函数方法进行操作。但是在这里有一个细节性的问题:虚函数是如何实现子类访问父类的函数的呢?

 

这里我们要知道一个叫虚函数表的概念,当我们书写一个类,给类的成员函数加上virtual后,这个类的大小就会相比较没有加virtual时,多了四个字节。

 

例子:

class Base
{
	public:
		virtual void func();
	private:
		int ma;
		int mb;
};

大家可以在VS的代码源目录文件中,键入命令:/d1reportSingleClassLayout查看想要查看的类:

       可以看到,多了一个叫vfptr的指针,占四个字节,而这个指针就是指向虚函数表,所谓虚函数表,就是存放了你设计的虚函数的地址,这也就能解释了,为什么子类可以访问父类的函数,就是通过虚函数指针,访问了虚函数表中函数。

这里要注意一点:如果子类也定义了一个虚函数并且与父类的同名,那么虚函数表中的函数就会把父类的虚函数地址替换成子类的。

       关于虚函数表:虚函数表是在编译阶段生成的,父类有父类的vfptr指向的虚函数表,子类有子类的,当虚函数表生成后,存放在内存的.rodata段,也就是只读数据段,只可以读取,不可以修改。

那些函数可以成为虚函数?那些函数又不能呢?

能否成为虚函数的判定方法只有两点:

  1. 能够产生函数符号地址;
  2. 必须依赖于对象;(只能通过对象的前四个字节 vfptr 才能访问虚函数表,进而访问虚函数的地址,)

基于以上两点,可以分析出能够成为虚函数的有:

  1. 析构函数
  2. 普通成员函数

而不能成为虚函数的有:

  1. 构造函数:构造函数在调用时,还没有产生对象;
  2. 带静态关键字static的函数:静态成员函数是类的组成部分,不是对象的,所有对象共享一份,没必要设为虚函数,静态成员函数有没办法继承;
  3. 内联函数:由于内联函数在编译时期被展开,变成了代码块,提高了编译运行效率,但是虚函数的动态绑定是在运行时间完成的,所以没法设成虚函数;
  4. 友元函数:友元函数不是类的成员函数,不支持继承友元函数,更不能设为虚函数了
  5. 普通函数:这个就很好理解了,都不在类里面,更别提继承绑定什么的了

纯虚函数

知道了虚函数,理解纯虚函数就不难了,虚函数中总有一些特例情况,在基类中会有一些成员方法没法实现,只能设成纯虚函数,再交给继承类具体实现功能。

比如如下代码:

class CMan 
{ 
    public:   
        virtual void talk() = 0; 
};

设计一个类:人,这个人的动作是talk,说,但是说话这方法怎么具体实现呢,只能通过子类具体实现相关的内容,这就是纯虚函数。

 

关于虚函数的内容我大概就总结了这么多,大致上把虚函数的内容总完了,还有就是根据虚函数的扩展知识,动态绑定之类的,呢些就要和静态绑定和继承派生结合着说了,后面再做总结。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!