啃书《C++ Primer Plus》 面向对象部分 虚机制——虚函数表、虚指针

长文干货预警


虚机制,一个听起来不好惹的角色,却是C++面向对象部分的精髓。不得不承认的是,这部分的内容有些多,也不太好理解。但同样不得不承认的是,虚机制在面向对象部分准确说是多态特性发挥着举足轻重的作用。可以说没有了虚机制,C++的面向对象就没有了灵魂。

因此,这一篇,我们就来整理有关虚机制的内容。本文的内容思维导图如下:
在这里插入图片描述
有关静态编联和动态编联的内容,可以参考另一篇博文:

啃书《C++ Primer Plus》面向对象部分 静态联编与动态联编


虚函数的创建和实现

这虚函数也是函数啊,唯一不同的就是它比较虚~~

因此,只需要在成员函数前面加上“虚”就完事了。

虚函数必须是成员函数

  • 这里,需要强调,虚函数必须是成员函数!!!
    对于这样的定义:
class A{
   
public:
    static virtual void f(){
   }	//企图定义一个静态的虚函数
};

编译器会给予报错:
在这里插入图片描述
告知静态的和虚的不允许同时出现。

这样的规定不难理解,只需要认识到,静态函数是仅属于类的,而成员函数“属于”对象。
虚函数提供了一种父类声明,子类实现的机制,这与静态函数仅属于类是冲突的。

虚函数的声明

刚刚说到,在成员函数前加上“虚”的修饰,就可以让它变成虚函数。这个"虚"就是英文单词virtual

class A{
   
public:
	virtual void f(){
   }//在A类中定义了一个虚函数f
};

在子类中重写这个虚函数时,则可以省略掉virtual关键字

class A{
   
public:
	virtual void f(){
   }//基类中定义了一个虚函数
};
class B: public A{
   
public:
	void f(){
   }//派生类中重写虚函数可以省略virtual
};

override与overwrite

这里介绍两个概念:overrideoverwrite

override的意思是重写虚函数,代表着子类给父类的某些虚函数提供一种实现,这是虚函数实现多态最常见的途径,即父类声明函数,子类提供实现。

在刚刚的例子中,B类重新实现了A类的虚函数f的行为就是一种重写。

overwrite译作中文应该叫“覆盖”,(不过由于翻译的五花八门,因此博主还是建议改概念使用英文来记忆比较妥当。)这个概念的并不仅仅出现在虚函数的范围中,在一般成员函数中也有所体现。

具体的说,就是当子类使用了父类中出现过的函数名称时,不论其返回类型、参数列表,是否被const修饰等因素是否相同,子类的该函数会覆盖所有的同名父类函数。

虚函数也不例外,也难逃overwrite的魔爪

#include<iostream>
using namespace std;
class A{
   
public:
	/*基类定义两个版本的函数f*/
    virtual void f(){
   cout << "func f in class A" << endl;}				
    virtual void f(int k){
   cout << "func f in class A and " << k << endl;}
};

class B:public A{
   
public:
	/*派生类重写了其中一个函数f*/
    virtual void f(){
   cout << "func f in class B" << endl;}
    //overwrite了另一个版本的函数,在B类作用域中没有带有一个整型参数的f函数
};

int main()
{
   
    A* pa = new B();
    pa->f();
    pa->f(10);
    
    B pb = new B();
    pb->f();
    pb->f(10);	//这个调用将会报错,B类中没有这个函数
	delete p;
}

虚函数表和虚指针

说了这么多有关虚函数的使用,是时候来介绍虚函数的原理了,书中在介绍动态联编处理虚函数的时候用到了这样的描述:

编译器必须生成能够在程序运行时选择正确虚方法的代码,这称为动态联编(dynamic binding),又称为晚联编(late binding)

这段用来进行动态联编的代码便是虚函数的原理,这其中就包含了虚函数表虚指针

虚函数表

虚函数表叫做Virtual Table,简称V-Table
简单些说,就是放置了一个类中所有虚函数指针的表,是一个函数指针数组

下面来说明各种情况下虚函数表的形态

无继承时

例如对于下面的类:

  • 44
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值