C++多态

C++多态教程

面向对象 的三大特征为:封装、继承 和多态,这三种机制能够有效提高程序的可读性、可扩充性和可重用性。“多态(polymorphism)” 指的是同一名字的事物可以完成不同的功能。

多态可以分为编译时的多态和运行时的多态。前者主要是指 函数的重载(包括运算符的重载)、对重载函数的调用,在编译时就能根据实参确定应该调用哪个函数,因此叫编译时的多态;而后者则和继承、虚函数等概念有关。

C++多态详解

有了虚函数,基类指针指向基类对象时就使用基类的成员(包括 成员函数成员变量 ),指向派生类对象时就使用派生类的成员。换句话说,基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)。

C++ 提供多态的目的是:可以通过基类指针对所有派生类(包括直接派生和间接派生)的成员变量和成员函数进行 “全方位” 的访问,尤其是成员函数。如果没有多态,我们只能访问成员变量。

构成多态的条件

  • 必须存在继承关系;
  • 继承关系中必须有同名的虚函数,并且它们是覆盖关系(函数原型相同)。
  • 存在基类的指针,通过该指针调用虚函数。

案例

C++多态

C++多态的使用

#include <iostream> #include <cstring> using namespace std; //Person类 class Person { public: Person(string name, int age):m_name(name),m_age(age) { } void info() { cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl; } protected: string m_name; int m_age; }; class Student:public Person { public: Student(string name, int age, float score):Person(name, age),m_score(score) { } void info() { cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl; } protected: float m_score; }; int main() { cout << "嗨客网(www.haicoder.net)\n" << endl; Person *person = new Person("HaiCoder", 18); person->info(); Student *student = new Student("HaiCoder", 18, 99); student->info(); return 0; }

程序运行后,控制台输出如下:

01_C多态.png

我们分别定义了一个 Person 类和一个 Student 类,Student 类继承自 Person 类,接着,在 main 函数里面,我们分别实例化了一个 Person 对象和一个 Student 对象。

最后,我们分别调用了 Person 类对象的 info 方法和 Student 类对象的 info 方法,我们发现,它们各自调用了自己的 info 函数,现在,我们用 Student 来实例化 Person 类,我们修改程序,如下:

#include <iostream> #include <cstring> using namespace std; //Person类 class Person { public: Person(string name, int age):m_name(name),m_age(age) { } void info() { cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl; } protected: string m_name; int m_age; }; class Student:public Person { public: Student(string name, int age, float score):Person(name, age),m_score(score) { } void info() { cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl; } protected: float m_score; }; int main() { cout << "嗨客网(www.haicoder.net)\n" << endl; Person *person = new Person("HaiCoder", 18); person->info(); person = new Student("HaiCoder", 18, 99); person->info(); return 0; }

程序运行后,控制台输出如下:

02_C多态.png

这次,我们用 Student 类实例化了 Person 类,最终调用 info 函数,此时的 info 函数还是调用的 Person 类的,这不是我们想要的效果,我们期望的是还是调用 Student 类的 info 函数。

也就是说通过基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数。为了能让基类指针访问派生类的成员函数,C++ 增加了虚函数(Virtual Function),现在,我们将 info 函数声明为虚函数,修改程序如下:

#include <iostream> #include <cstring> using namespace std; //Person类 class Person { public: Person(string name, int age):m_name(name),m_age(age) { } virtual void info() { cout << "Call Person info, Name = " << this->m_name << " Age = " << this->m_age << endl; } protected: string m_name; int m_age; }; class Student:public Person { public: Student(string name, int age, float score):Person(name, age),m_score(score) { } virtual void info() { cout << "Call Student info, Name = " << this->m_name << " Age = " << this->m_age << " Score = " << m_score << endl; } protected: float m_score; }; int main() { cout << "嗨客网(www.haicoder.net)\n" << endl; Person *person = new Person("HaiCoder", 18); person->info(); person = new Student("HaiCoder", 18, 99); person->info(); return 0; }

程序运行后,控制台输出如下:

03_C多态.png

这次,我们使用 person 对象可以调用到 Student 实例的 info 方法了,即,我们通过虚函数实现了多态。

C++多态总结

基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)。

C++ 提供多态的目的是:可以通过基类指针对所有派生类(包括直接派生和间接派生)的成员变量和成员函数进行 “全方位” 的访问,尤其是成员函数。如果没有多态,我们只能访问成员变量。