多态性是面向对象程序设计语言的又一重要特征,多态(polymorphism)通俗的讲,就是用一个相同的名字定义许多不同的函数,这些函数可以针对不同数据类型实现相同或类似的功能,即所谓的 “一个接口,多种实现” 。
#include <iostream>
using namespace std;
class Shape{ //形状
public:
virtual void draw(){ //如果不加 virtual关键字修饰,那么下方for()循环就会一直调用该成员函数。
cout << "Shape draw" << endl;
}
};
class Rect : public Shape{ //矩形
public:
void draw(){
cout << "Rect draw" << endl;
}
};
class Circle : public Shape{ //圆形
public:
void draw(){
cout << "Circle draw" << endl;
}
};
class Ellipse : public Shape{ //椭圆
public:
void draw(){
cout << "Ellipse draw" << endl;
}
};
int main(void) {
Shape *ps[128] = {0};
ps[0] = new Rect;
ps[1] = new Circle;
ps[2] = new Ellipse;
for(int i = 0; ps[i] != NULL; i++){
ps[i]->draw();
}
return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy05$ ./a.out
Rect draw
Ellipse draw
Circle draw
被 virtual 关键字修饰的成员函数称为虚函数。
如果将基类中的某个成员函数声明为虚函数,那么子类中与该函数具有相同原型的成员函数也就是虚函数,并且对基类中版本形成覆盖,即函数重写。
如果子类提供了对基类函数有效的覆盖,那么通过指向子类对象的基类指针,或者通过引用子类对象的基类引用,调用该虚函数,实际被执行将是子类中的覆盖版本,而不再是基类中的原始版本,这种语法现象被称为多态。
多态的意义在于,一般情况下,调用那个类的成员函数由调用者指针或者引用本身类型决定的,而有了多态,调用那个类的成员函数由调用者指针或者引用实际对象的类型决定。
这样一来,源自同一种类型的同一种激励,竟然可以产生多种不同的响应,也就是对于同一个函数调用,能够表达出不同的形态,即为多态。
虚函数覆盖的条件:
#include <iostream>
using namespace std;
class A{};
class B : public A {};
class Base{
virtual void fun() {
cout << "Base fun()" << endl;
}
virtual A *foo(void){
cout << "Base foo()" << endl;
}
};
class Derived : public Base {
void fun(){
cout <<"Derived fun()" << endl;
}
B *foo(void){
cout << "Derived foo()" << endl;
}
};
int main() {
Derived d1;
Base *pd1 = &d1;
pd1->func(); //输出子类中的func()函数
Base& pd2 = d1;
pd2.foo(); //输出子类中的foo()函数
return 0;
}
产生多态的条件:
#include <iostream>
using namespace std;
class A{};
class B : public A {};
class Base{
virtual void fun() {
cout << "Base fun()" << endl;
}
virtual A *foo(void){
cout << "Base foo()" << endl;
}
};
class Derived : public Base {
void fun(){
cout <<"Derived fun()" << endl;
}
B *foo(void){
cout << "Derived foo()" << endl;
}
};
int main() {
Derived d1;
Base b1 = d1;
b1.func(); //调用的是基类当中的 fun() 函数
return 0;
}
class A{};
class Base{
void fun() {
cout << "base" << endl;
}
A *foo(void){ //A *foo(A *this)
fun(); //this->fun();
}
};
class Derived : public Base {
void fun(){
cout <<"Derived" << endl;
}
};
int main() {
Derived d1;
d1.foo(); //d1.foo(&d1); 调用的是子类中的fun()函数
}