1.什么是多态?
多态是指函数调用的多种形态,使我们调用函数更加灵活。
多态分为静态多态与动态多态
1)静态多态:静态多态指的是编译时的多态,通过函数重载实现。根据函数命名规则找到函数地址,从而实现调用不同的方法。
2)动态多态(运行时):父类指针或引用调用重写虚函数
a.父类指针或引用指向父类,调用的就是父类的虚函数,指向哪个子类就去调用哪个子类里相应的虚函数。
动态的多态构成的条件:
1)必须通过基类的指针或者引用调用虚函数
2)被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
满足多态的条件时:
跟对象有关,父类的指针或引用指向哪个对象就调用哪个对象的虚函数
不满足多态的条件:
跟类型有关,调用的类型是谁,就调用谁。
虚函数的定义:只有类的非静态成员函数才可以称作是虚函数。
虚函数的virtual与虚继承的virtual没有关系。
虚函数是为了实现多态而虚继承是为了解决菱形继承带来的数据冗余和二义性。
虚函数的重写:
派生类中有一个跟基类完全相同的虚函数(即返回值类型,函数名,参数列表完全相同)则称子类的虚函数重写了基类的虚函数。
虚函数的重写的例外:
1)协变(函数名和参数相同,返回值是指针或者引用,俩个返回值须有父子关系)
基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类的指针或者引用。称为协变
class A{
};
class B : public A {
};
class Person {
public:
virtual A* f() {
return new A;}
};
class Student : public Person {
public:
virtual B* f() {
return new B;}
};
2)
析构函数的重写(基类与派生类析构函数的名字不同)但底层都是destructor
如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写
class Person {
public:
virtual ~Person() {
cout << "~Person()" << endl;}
};
class Student : public Person {
public:
virtual ~Student() {
cout << "~Student()"