C++多态性

来源:互联网 发布:linux tomcat启动脚本 编辑:程序博客网 时间:2024/06/16 11:57

假设我们有三个类Person、Teacher、Student它们之间的关系:Teacher、Student继承Person。
Demo1

#ifndef __OBJEDT_H__#define  __OBJEDT_H__#include <string>#include <iostream>class Person{public:    Person(const string& name, int age) : m_name(name), m_age(age)    {    }    void ShowInfo()    {        cout << "姓名:" << m_name << endl;        cout << "年龄:" << m_age << endl;    }protected:    string  m_name;     //姓名    int     m_age;      //年龄};class Teacher : public Person{public:    Teacher(const string& name, int age, const string& title)        : Person(name, age), m_title(title)    {    }    void ShowInfo()    {        cout << "姓名:" << m_name << endl;        cout << "年龄:" << m_age << endl;        cout << "职称:" << m_title << endl;    }private:    string  m_title;        //职称};class Student : public Person{public:    Student(const string& name, int age, int studyId)        : Person(name, age), m_studyId(studyId)    {    }    void ShowInfo()    {        cout << "姓名:" << m_name << endl;        cout << "年龄:" << m_age << endl;        cout << "学号:" << m_studyId << endl;    }private:    int m_studyId;          //学号};#endif  //__OBJEDT_H__

测试

void test(){    Person* pPerson = new Person("张三", 22);    Teacher* pTeacher = new Teacher("李四", 35, "副教授");    Student* pStudent = new Student("王五", 18, 20151653);    pPerson->ShowInfo();    cout << endl;    pTeacher->ShowInfo();    cout << endl;    pStudent->ShowInfo();    cout << endl;    delete pPerson;    delete pTeacher;    delete pStudent;}

结果

    姓名:张三    年龄:22    姓名:李四    年龄:35    职称:副教授    姓名:王五    年龄:18    学号:20151653

这里的ShowInfo就是一个普通的函数。pPerson、pTeacher和pStudent三个对象调用ShowInfo分别展示自己的信息。
我们知道:父类的指针是可以指向子类的对象的。我们把上面的测试代码稍微改一下:

void test(){    Person* pPerson = new Person("张三", 22);    Person* pTeacher = new Teacher("李四", 35, "副教授");    Person* pStudent = new Student("王五", 18, 20151653);    pPerson->ShowInfo();    cout << endl;    pTeacher->ShowInfo();    cout << endl;    pStudent->ShowInfo();    cout << endl;    delete pPerson;    delete pTeacher;    delete pStudent;}

结果

    姓名:张三    年龄:22    姓名:李四    年龄:35    姓名:王五    年龄:18

这时,pTeacher和pStudent只输出了姓名和年龄,并没有输出子类所具有的特性(职称和学号)。这应该不是你期望的结果,你可能期望pTeacher和pStudent输出老师和学生的完整信息,这时就需要用虚函数。

虚函数
我们把Person中的ShowInfo成员改成虚函数(在前面加上virtual),代码如下:

class Person{public:    Person(const string& name, int age) : m_name(name), m_age(age)    {    }    virtual void ShowInfo()    {        cout << "姓名:" << m_name << endl;        cout << "年龄:" << m_age << endl;    }protected:    string  m_name;     //姓名    int     m_age;      //年龄};

结果

    姓名:张三    年龄:22    姓名:李四    年龄:35    职称:副教授    姓名:王五    年龄:18    学号:20151653

总结
虚函数用法要点:

虚函数的声明方式:virtual RETURN_TYPE functionName(ARGS 参数列表);虚函数作用:现实C++中的多态,进行动态绑定(父类指针可指向子类的对象),直到运行时才知道要调用哪个版本(哪个类定义)的函数;我们必要对虚函数进行定义;一旦父类的成员函数声明virtual,其子类的函数不管有没有声明为virtual,都是虚函数;如果虚函数使用默认实参,父类和子类定义的默认实参最好一致。 注:当缺省参数和虚函数一起出现的时候到底用哪个默认值呢?虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。也就是 指针是哪种类型,就调用该类型对应的类中,该函数定义时的缺省值。
class Person{public:    virtual void SetAge(int age = 0)    {        m_age = age;    }    //... 省略};class Teacher : public Person{public:    virtual void SetAge(int age = 1)    {        m_age = age;    }    //... 省略};class Student : public Person{public:    virtual void SetAge(int age = 2)    {        m_age = age;    }    //... 省略};
void test(){    Person* pPerson = new Person("张三", 22);    Teacher* pTeacher = new Teacher("李四", 35, "副教授");    Student* pStudent = new Student("王五", 18, 20151653);    pPerson->SetAge();    pTeacher->SetAge();    pStudent->SetAge();    pPerson->ShowInfo();    cout << endl;    pTeacher->ShowInfo();    cout << endl;    pStudent->ShowInfo();    cout << endl;    delete pPerson;    delete pTeacher;    delete pStudent;}

结果

    姓名:张三    年龄:0    姓名:李四    年龄:1    职称:副教授    姓名:王五    年龄:2    学号:20151653
void test(){    Person* pPerson = new Person("张三", 22);    Person* pTeacher = new Teacher("李四", 35, "副教授");    Person* pStudent = new Student("王五", 18, 20151653);    pPerson->SetAge();    pTeacher->SetAge();    pStudent->SetAge();    pPerson->ShowInfo();    cout << endl;    pTeacher->ShowInfo();    cout << endl;    pStudent->ShowInfo();    cout << endl;    delete pPerson;    delete pTeacher;    delete pStudent;}

结果

    姓名:张三    年龄:0    姓名:李四    年龄:0    职称:副教授    姓名:王五    年龄:0    学号:20151653