zoukankan      html  css  js  c++  java
  • 4.2 C++虚成员函数

    参考:http://www.weixueyuan.net/view/6371.html

    总结:

      virtual关键字仅用于函数声明,如果函数是在类外定义,则不需要再加上virtual关键字了。

      在C++中只有类中的成员函数能被声明为虚函数,而对于顶层函数则不能声明为虚函数。  

      声明虚函数是为了构成多态。

      实际上我们只需要将基类中的display函数通过virtual关键字声明为虚函数,之后即使在派生类中display函数声明时未加上virtual关键字,它在所有的派生类中都将自动成为虚函数。

      和普通的成员函数一样,虚成员函数同样可以被继承。

    在上一节中已经提到了虚函数的声明方法了,就是在函数返回类型前加上virtual关键字。virtual关键字仅用于函数声明,如果函数是在类外定义,则不需要再加上virtual关键字了,在C++中只有类中的成员函数能被声明为虚函数,而对于顶层函数则不能声明为虚函数,原因很简单,声明虚函数是为了构成多态,而构成多态的第一个条件就是需要继承关系,顶层函数很明显是不具有继承关系的,因此也就不能被声明为虚函数了。

    例1:
    #include<iostream>
    using namespace std;
    
    class base
    {
    public:
        virtual void display();
    };
    
    class derived: public base
    {
    public:
        virtual void display();
    
    };
    
    void base::display()
    {
        cout<<"I'm base class!"<<endl;
    }
    
    void derived::display()
    {
        cout<<"I'm derived class!"<<endl;
    }
    
    int main()
    {
        base * p = new base;
        p->display();
        delete p;
        p = new derived;
        p->display();
        delete p;
        return 0;
    }
    在本例中,我们将两个类中的display函数在类内部声明,类外部定义,当然这么修改并不会改变程序的运行结果。在本例中我们需要注意的是在类内声明时display函数通过在返回类型前添加了virtual关键字而被声明为了虚函数,而在类外定义时,display函数的返回类型前并未添加virtual关键字。
    
    另外在例1中,我们在基类和派生类中的display函数声明时都加上了virtual关键字,以表示将其声明为虚函数,而实际上这是不需要的,我们只需要将基类中的display函数通过virtual关键字声明为虚函数,之后即使在派生类中display函数声明时未加上virtual关键字,但它在所有的派生类中都将自动成为虚函数。
    
    例2:
    #include<iostream>
    using namespace std;
    
    class base
    {
    public:
        virtual void display();
    };
    
    class derived: public base
    {
    public:
        void display();
    
    };
    
    void base::display()
    {
        cout<<"I'm base class!"<<endl;
    }
    
    void derived::display()
    {
        cout<<"I'm derived class!"<<endl;
    }
    
    int main()
    {
        base * p = new base;
        p->display();
        delete p;
        p = new derived;
        p->display();
        delete p;
        return 0;
    }
    在本例中,我们将例1中派生类的display成员函数声明时所用的virtual关键字去掉,编译并运行程序,结果显示程序运行结果仍然保持不变。

    和普通的成员函数一样,虚成员函数同样可以被继承。

    例3:
    #include<iostream>
    using namespace std;
    
    class base
    {
    public:
        virtual void hello(){cout<<"Hello!"<<endl;}
    };
    
    class derived: public base
    {
        //......
    };
    
    int main()
    {
        base * p = new base;
        p->hello();
        delete p;
        p = new derived;
        p->hello();
        delete p;
        derived d;
        d.hello();
        return 0;
    }
    在本例中,派生类derived中无新增的成员变量或成员函数,它是base类的派生类。我们直接来看主函数。在主函数中依然是定义一个base类类型的指针,然后先后指向基类和派生类的对象。在此例中,因为派生类中并不存在与基类hello函数具有相同函数名的虚函数(继承过来的hello函数与基类中的hello函数并未构成遮蔽关系),因此并未构成多态,自始至终都是调用的都是基类的hello函数。之后又定义了一个派生类对象d,这个对象调用hello函数,当然则个hello同样是继承自基类base中的hello函数了。从这个程序很明显可以看出虚函数是具有继承特性的,这一点它与普通函数一般无二。
     
  • 相关阅读:
    土豆网自动播放代码
    js倒计时小插件(兼容大部分浏览器)
    带按钮的网页播放器代码(附文件)
    列出目录下所有文件
    day19 进度条 & 随机验证码
    day18 json与pickle
    day14.2_三元表达式、列表生成式
    day14.1_生成器
    day13_迭代器
    day12.2_完善装饰器
  • 原文地址:https://www.cnblogs.com/yongpan/p/7659188.html
Copyright © 2011-2022 走看看