目录
一、多态的概念
在C++中有两种多态性,一种是静态的多态、一种是动态的多态;
静态的多态:函数重载,看起来调用同一个函数却有不同的行为。静态:原理是编译时实现。
动态的多态:一个父类的引用或指针去调用同一个函数,传递不同的对象,会调用不同的函数。动态:原理是运行时实现。
二、多态的定义及实现
1.多态的构成条件
在继承中要构成多态还有两个条件:
1. 必须通过基类的指针或者引用调用虚函数。
2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
2.虚函数
虚函数:即被virtual修饰的类成员函数称为虚函数。
一旦定义了虚函数,该基类的派生类中同名函数也自动成为了虚函数。也就是说在派生类中有一个和基类同名的函数,只要基类加了virtual修饰,派生类不加virtual修饰也是虚函数。
虚函数只能是类中的一个成员函数,不能是静态成员或普通函数。
3.虚函数的重写
虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。
//买票
class Person
{
public:
virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
//学生买票
class Student : public Person
{
public:
virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
//军人买票
class Soldier : public Person
{
public:
void BuyTicket() { cout << "优先-买票-半价" << endl; }
};
通过对虚函数的重写,就能够实现多态:
//买票
class Person
{
public:
virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
//学生买票
class Student : public Person
{
public:
virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
//军人买票
class Soldier : public Person
{
public:
void BuyTicket() { cout << "优先-买票-半价" << endl; }
};
//构成多态,传的哪个类型的对象,调用的就是这个类型的虚函数 --- 跟对象有关
//不构成多态,调用就是P的类型 --- 跟类型有关
void Func(Person& p) //或void Func(Person* p)
{
p.BuyTicket(); //p->BuyTicket();
}
int main()
{
Person ps;
Func(ps); //没有任何身份去买票,一定是全价
Student st;
Func(st); //以学生的身份去买票,是半价
Soldier so;
Func(so); //以军人的身份去买票,是优先并且半价
return 0;
}
三、多态的原理
1.虚函数表指针
class Base
{
public:
virtual void Func1()
{
cout << "Func1()" << endl;
}
private:
int _b = 1;
char ch = 'A';
};
int main()
{
Base bb;
cout << sizeof(Base) << endl;
return 0;
}
2.虚函数表
class Base
{
public:
virtual void Func1() { cout << "Base::Func1()" << endl; }
virtual void Func2() { cout << "Base::Func2()" << endl; }
void Func3() { cout << "Base::Func3()" << endl; }
private:
int _b = 1;
};
class Derive : public Base
{
public:
virtual void Func1() { cout << "Derive::Func1()" << endl; }
private:
int _d = 2;
};
int main()
{
Base b;
Derive d;
return 0;
}
3.多态的原理
class Base
{
public:
virtual void Func1()
{ cout << "Base::Func1()" << endl; }
virtual void Func2()
{ cout << "Base::Func2()" << endl; }
void Func3()
{ cout << "Base::Func3()" << endl; }
private:
int _b = 1;
};
class Derive : public Base
{
public:
virtual void Func1()
{ cout << "Derive::Func1()" << endl; }
private:
int _d = 2;
};
int main()
{
Base b;
Derive d;
Base* p1 = &b;
p1->Func1();
p1 = &d;
p1->Func1();
return 0;
}