问题: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后就实现了不同的功能
我们只需在把基 类的成员函数设为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