虚函数

问题:1.什么是多态?


              父类指针指向一个子类对象,通过父类的指针调用子类的成员函数,这样使父类指针有多种形态。

           2.多态基于虚函数(virtual)完成,虚函数基于重写。

           3.哪些函数需要用到虚函数,什么时候实现多态?

          如果父类的指针指向子类对象,需使用子类的函数时就使用虚函数。

            4.什么时候出现父类指针指向子类对象?

          把不同的类型统一成同一种类,也就是说有共同的功能但是方式不同

                   例:CPerson 父类   CChina和CUSA两个类继承父类  CChina和CUSA有CPerson的全部功能

          5.虚函数实现多态的原理? 

                             通过维护一个虚函数列表v_table,虚函数列表的每个元素是一个函数指针

                 指向一个虚函数,或者子类重写函数。  需要vfptr记录这个类所使用那个虚函数列表
                 之后要用父类的指针调用虚函数,通过vfptr找到v_table列表中的函数调用

    注  v_table虚函数列表在编译期创建,

     vfptr指向表的指针创建对象的指针存在,是父类中的第一个数据成员,并且在构造函数的里初始化指向自己类中v_table


简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略

虚函数的继承

1.子类继承父类中的函数,若子类的函数没有重写父类的函数,

则虚函数列表Base::f()  Base::g()  Derive::f()  Derive::g()


2.重写了父类的函数 则覆盖父类相应的函数

则虚函数列表Derive::f()   Base::g()   Derive::g()

注 Base 表示父类  Derive表示派生类

声明:

   1.只需要在声明函数的类体中使用关键字“virtual”将函数声明为虚函数,而定义函数时不需要使用关键字“virtual”。

#include<iostream>
using namespace std;

class CWater
{
public:
	virtual void Show()   //  虚函数
	{
		cout << "CWater::Show" << endl;
	}
};


class CCoffee : public CWater
{
public:
	void Show()
	{
		cout << "CCoffee::Show" << endl;
	}
};


class CCoco :public CWater
{
public:
	void Show()
	{
		cout << "CCoco::Show" << endl;
	}
      这是一段伪代码 ,使用关键字vrtual后就实现了不同的功能

    2.当将基类中的某一 成员函数声明为虚函数后,派生类中的同名函数(函数名相同、参数列表完全一致、返回值类型相关)自动成为虚函数。
    3.如果声明了某个成员函数为虚函数,则在该类中不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。在以该类为 基类派生类中,也不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。
我们只需在把基 类的成员函数设为virtual,其 派生类的相应的函数也会自动变为虚函数。
   4.非 类的成员函数不能定义为虚函数,类的成员函数中 静态成员函数和 构造函数也不能定义为虚函数,但可以将 析构函数定义为虚函数。


代码:

class CFather
{
public:
	virtual void AA()
	{
		cout << "CFather::AA" << endl;
	}
	virtual void BB()
	{
		cout << "CFather::BB" << endl;
	}
	void CC()
	{
		cout << "CFather::CC" << endl;
	}
};

class CSon : public CFather
{
public:
	virtual void BB()
	{
		cout << "CSon::BB" << endl;
	}
	void CC()
	{
		cout << "CSon::CC" << endl;
	}
	virtual void DD()
	{
		cout << "CSon::DD" << endl;
	}
};



int main()
{

	cout << sizeof(CFather) << endl;

	CFather* father = new CSon;
	
	typedef void (*PFUN)();

	PFUN a = (PFUN)*((int*)*(int*)father+0);
	PFUN b = (PFUN)*((int*)*(int*)father+1);
	PFUN c = (PFUN)*((int*)*(int*)father+2);
	PFUN d = (PFUN)*((int*)*(int*)father+3);

	(*a)();
	(*b)();
	(*c)();

	//father->AA();
	//father->BB();
	//father->CC();
	//father->DD();

	//father->CFather::BB();   //  类名 作用已经确定调用谁的了   调用父类里的BB()函数需要加上父类的所属域


	system("pause");
	return 0;
}

       该代码运行结果:

4

  CFather::AA

CSun::BB

CSun::DD





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值