多态
1、覆写
覆写:派生类重写基类的虚函数。
1、只有虚方法和抽象方法才能被覆写。
2、相同的函数名。
3、相同的参数类型。
4、相同的返回值类型。
2、虚函数
virtual 修饰函数
3、机制
原理:
对于虚函数,采用动态联编:有虚函数的对象里有一个指针,指向虚函数表;
调用虚函数时,会根据对象里的指针找到表,从表中取出函数来执行
对于非虚函数,采用静态联编:编译时就确定调用哪个函数
差别:
静态联编效率高,动态联编支持多态
4、多态的限制
test_func(Human* h):
test_func(Human& h):使用指针或引用来使用对象时,才有多态
test_func(Human h):传值时,无多态
1、只有类的成员函数才能声明为虚函数
2、内联函数不能是虚函数
3、构造函数不能是虚函数
4、析构函数一般都声明为虚函数
5、重载:函数参数不同,不可设为虚函数
覆盖:函数参数、返回值相同,可以设为虚函数
6、返回值例外:
函数参数相同,但是返回值是当前对象的指针或引用时,也可以设为虚函数
例子:
#include <iostream>
#include <string.h>
#include <unistd.h>
using namespace std;
class Human {
private:
int a;
public:
virtual void eating(void) { cout<<"use hand to eat"<<endl; }
virtual ~Human() { cout<<"~Human()"<<endl; }
virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};
class Englishman : public Human {
public:
void eating(void) { cout<<"use knife to eat"<<endl; }
virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};
class Chinese : public Human {
public:
void eating(void) { cout<<"use chopsticks to eat"<<endl; }
virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};
void test_eating(Human& h)
{
h.eating();
}
void test_return(Human& h)
{
h.test();
}
int main(int argc, char **argv)
{
Human h;
Englishman e;
Chinese c;
test_return(h);
test_return(e);
test_return(c);
return 0;
}