虚函数和多态

来源:互联网 发布:制造业企业大数据分析 编辑:程序博客网 时间:2024/06/06 02:48

虚函数的概念
在类的成员函数前加virtual关键字,这个成员函数称为虚函数。
虚函数重写–当在子类的定义了一个与父类完全相同的虚函数时,则称子类的这个函数重写(也称覆盖)了父类的这个虚函数。

#include<iostream>using namespace std;class Personpublic:    virtual void BuyTickets()    {        cout << "买全价票" << endl;    }};class Student :public Person{public:    virtual void BuyTickets()//重写 覆盖    {        cout << "买半价票" << endl;    }};void fun(Person&p){    p.BuyTickets();}int main(){    Person p;    Student s;    fun(p);    fun(s);    s`stem("pause");    return 0;}

多态
当时用基类的指针或引用调用重写的虚函数时,指向父类的的就是父类的虚函数,指向子类的就是子类的虚函数。

总结:
派生类重写基类的虚函数构成多态要求函数名相同,返回值相同,参数相同(协变除外)。
在基类中定义了虚函数,在派生类中依旧保持虚函数的特性。
只有在类内才能定义虚函数,如果想在类外部定义虚函数,则需在类内部声明虚函数,然后在类外部定义并且在外部定义时不加virtual。
静态成员不能为虚函数。
构造函数不能为虚函数,虽然可以将operator=定义为虚函数,但是最好不要将operator=定义为虚函数,因为容易使用时容易引 起混淆。
不要在构造函数和析构函数里面调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会发生未定义的行为。
最好把基类的析构函数声明为虚函数。(why?另外析构函数比较特殊,因为派生类的析构函数跟基类的析构函数名称不一样,但 是构成覆盖,这里是因为编译器做了特殊处理)
重载,重写(覆盖),重定义(隐藏)三者的区别
重载:在同一作用域,函数名相同,参数不同,返回值可以不同
重定义(隐藏):不在同一作用域,分别在基类和派生类,函数名相同
重写(覆盖):不在同一作用域,分别在基类和派生类,函数名相同,参数相同,返回值相同 访问限定符可以不同,基类必须有virtual关键。
在基类和派生类的关系中,只要不构成重写就构成重定义。
纯虚函数
在虚函数的形参后加=0构成纯虚函数,所在的类叫做抽象类,抽象类不能实例化对象。纯虚函数在派生类中重新定义以后,派生类才能实例化出对象

//纯虚函数class Person{public:    virtual void Display()=0    {}}; 

友元关系不能继承,基类定义了static成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例。

原创粉丝点击