c++(虚函数与虚表)

c++

虚函数

  • 前言:c++中的虚函数就与java,c#这类型面向对象编程语言中的抽象函数类似,是可以让子类重写的函数,但需要知道的是,仅仅在重写一方面相似,差别还是很大的.
  • 虚函数的用法:在类成员方法声明时返回值前加上virtual关键字来标记这个函数是一个虚函数,子类继承后可以复写(也可以不复写)该方法。
  • 虚函数与普通函数在继承中特性比较
  1. 虚函数可以被子类重写,重写后用父类指针指向子类对象,调用结果是子类重写后的函数,若为普通函数则这种情况下调用的其实是父类的函数。
  2. 虚函数重写后无需标记,仍然是虚函数,即可以被下一代继续重写
  • 纯虚函数:纯虚函数的声明方式是在虚函数声明参数括号后加一个=0。
  1. 含有纯虚函数的类无法实例化得到对象。
  2. 子类必须复写纯虚函数,否则无法通过编译。
  3. 纯虚函数被复写后成为虚函数。

例子

#include <iostream>
#include <vector>
using namespace std;
class base
{
public:
	void num_cout_ordinary() { cout << "这是基类普通方法的输出" << endl; }
	virtual void num_cout_hypothetical() { cout << "这是基类虚函数的输出" << endl; }
	virtual void num_cout_purely()=0 { cout << "这是基类纯虚函数的输出" << endl; }
};
class first :public base
{
public:
	 void num_cout() { cout << "这是第一代子类普通方法的输出" << endl;  }
	 void num_cout_hypothetical() { cout << "这是第一代子类虚函数的输出" << endl; }
	 void num_cout_purely(){ cout << "这是第一代子类重写后纯虚函数的输出" << endl; }
};
class second :public first
{
public:
	void num_cout() { cout << "这是第二代子类(孙子类)普通方法的输出" << endl; }
	void num_cout_hypothetical() { cout << "这是第二代子类(孙子类)虚函数的输出" << endl; }
	void num_cout_purely(){ cout << "这是第二代子类(孙子类)重写后纯虚函数的输出" << endl; }
};
int main()
{
	base*a1, *a2;
	a1 = new first();
	a2 = new second();
	
	a1->num_cout_ordinary();
	a2->num_cout_ordinary();

	a1->num_cout_hypothetical();
	a2->num_cout_hypothetical();

	a1->num_cout_purely();
	a2->num_cout_purely();

	return 0;
}

该例子的运行结果如下:
在这里插入图片描述
当我注释了一代子类的"纯虚函数”复写后编译器报错,我无法通过编译
当我注释了二代子类的“纯虚函数”复写后结果如下:
在这里插入图片描述

虚表

  • :虚表这个东西和虚函数的调用息息相关,虚函数这个东西的调用流程和普通函数是不一样的,而构建虚表就是为了给虚函数的调用走一个中介关系。
  • 对比虚函数与普通函数调用流程:普通函数的空间位置在编译时确定,并静态确定了调用方式。而虚函数是在编译时确定了函数的位置但调用方式是动态的。虚函数调用流程如下:对象指针->对象中的虚指针->虚表->虚函数;这样一个流程。
  • 虚表在哪里:虚表这个东西就是一个类有一个,其中存了指向这个类包含的虚函数的指针,比如这个类有一个虚函数,虚表就一个指针,没有虚函数,干脆就没有虚表。而一个对象是没有自己的虚表的,只有一个虚指针,指向了这个类的虚表。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值