一、多态的概念
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态。
举个例子:比如有一个玻璃杯,它的内部可以装水,可以装牛奶,也可以装咖啡。
二、多态的定义及使用方法
1. 须通过基类的指针或者引用调用虚函数
2. 被调用的函数必须是虚函数,且派生类须对基类的虚函数进行重写
#include <iostream>
using namespace std;
class Drink
{
public:
virtual void Show();
};
void Drink::Show()
{
cout << "Drink" << endl;
}
class Water :public Drink
{
public:
void Show();
};
void Water::Show()
{
cout << "Water" << endl;
}
class Milk :public Drink
{
public:
void Show();
};
void Milk::Show()
{
cout << "Milk" << endl;
}
class Coffee :public Drink
{
public:
void Show();
};
void Coffee::Show()
{
cout << "Coffee" << endl;
}
void Bottle(Drink* p)
{
p->Show();
}
int main()
{
Drink* p1 = new Water;
Drink* p2 = new Milk;
Drink* p3 = new Coffee;
Bottle(p1);
Bottle(p2);
Bottle(p3);
system("pause");
return 0;
}
在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用.
三、引用实现多态
#include <iostream>
using namespace std;
class Drink
{
public:
virtual void Show();
};
void Drink::Show()
{
cout << "Drink" << endl;
}
class Water :public Drink
{
public:
void Show();
};
void Water::Show()
{
cout << "Water" << endl;
}
class Milk :public Drink
{
public:
void Show();
};
void Milk::Show()
{
cout << "Milk" << endl;
}
class Coffee :public Drink
{
public:
void Show();
};
void Coffee::Show()
{
cout << "Coffee" << endl;
}
void Bottle(Drink &rd)
{
rd.Show();
}
int main()
{
Water a1;
Milk a2;
Coffee a3;
Drink& ra1 = a1;
Drink& ra2 = a2;
Drink& ra3 = a3;
Bottle(ra1);
Bottle(ra2);
Bottle(ra3);
system("pause");
return 0;
}
引用不像指针灵活,指针可以随时改变指向,而引用只能指代固定的对象,在多态性方面缺乏表现力,所以我们以后再谈起多态一般说是指针。
四、虚函数的注意事项
1、只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加。
2、为了方便,你可以只将基类中的函数声明为虚函数,这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数。
3、当在基类中定义了虚函数时,如果派生类没有定义新的函数来遮蔽此函数,那么将使用基类的虚函数。
4、只有派生类的虚函数覆盖基类的虚函数(函数原型相同)才能构成多态(通过基类指针访问派生类函数)。
(例如:基类虚函数的原型为virtual void func();派生类虚函数的原型为virtual void func(int);那么当基类指针 p 指向派生类对象时,语句p -> func(100);将会出错,而语句p -> func();将调用基类的函数。)
5、构造函数不能是虚函数。对于基类的构造函数,它仅仅是在派生类构造函数中被调用,这种机制不同于继承。也就是说,派生类不继承基类的构造函数,将构造函数声明为虚函数没有什么意义。
6、析构函数可以声明为虚函数,而且有需要时必须声明为虚函数。