目录
1. 多态的定义
多态就是多种形态。
1.1 多态的构成条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。
比如Student继承了 Person。Person对象买票全价,Student对象买票半价。
【条件】
1. 虚函数重写。
2. 必须父类指针或引用去调用虚函数。
1.2 虚函数
virtual修饰的成员函数称为虚函数。
class Person { public: virtual void BuyTicket() { cout << "买票-全价" << endl;} };
1.3 虚函数重写
子类中有一个跟基类完全相同的虚函数(返回值、函数名、参数列表完全相同),然后修改子类的函数体,称子类的虚函数重写了基类的虚函数。
class Person { public: virtual void BuyTicket() { cout << "买票-全价" << endl; } }; class Student : public Person { public: virtual void BuyTicket() { cout << "买票-半价" << endl; } }
【两个例外】
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。
class Person { public: virtual ~Person() {cout << "~Person()" << endl;} }; class Student : public Person { public: virtual ~Student() { cout << "~Student()" << endl; } }; // 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函 数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。 int main() { Person* p1 = new Person; Person* p2 = new Student; delete p1; //p1->destructor() + operator delete(p1) delete p2; //指向父类调父类,指向子类调子类 return 0; }