• C++程序设计方法3:虚函数


    向上映射与向下映射

    派生类对象转换成基类对象,称为向上映射。

    而基类对象转换成派生类对象,称为向下映射;

    向上映射可由编译器自动完成,是一种隐式的自动类型转化;

    凡是接受基类对象的地方(如函数参数)都可以使用派生类对象,编译器会自动将派生类

    转化为基类对象以便使用;

    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
        void print()
        {
            cout << "Base::print()" << endl;
        }
    };
    
    class Derive :public Base
    {
    public:
        void print()
        {
            cout << "Derive:print()" << endl;
        }
    };
    
    void fun(Base obj)
    {
        obj.print();
    }
    
    int main()
    {
        Derive d;
        d.print();
        fun(d);//Base::print()自动转化为基类的对象
        return 0;
    }

    虚函数

    对于被派生类重写的成员函数,若它在基类中被声明为虚函数,则通过基类指针或者引用

    调用该成员函数时,编译器将根据所指向对象的实际类型决定是调用基类中的函数还是派生类中重写的函数;

    class Base

    {

    public:

      virtual 返回类型 函数名(形式参数);//虚函数

    };

    若某个成员函数在基类中声明为虚函数,当派生类重新写他时,无论是否声明为虚函数,

    该成员函数都可以仍然是虚函数;

    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
        virtual void print()
        {
            cout << "Base::print()" << endl;
        }
    };
    
    class Derive : public Base
    {
    public:
        void print()
        {
            cout << "Derive::print()" << endl;
        }
    };
    
    void fun(Base& obj)
    {
        obj.print();//obj是Base类对象的引用
    }
    
    int main()
    {
        Derive d;
        d.print();
        fun(d);
        return 0;
    }

    虚析构函数的使用例子:

    #include <iostream> using namespace std; class B { public: virtual void show() { cout << "B.show() "; } virtual ~B() { cout << "~B() "; } }; class D : public B { public: void show() { cout << "D.show() "; } ~D() { cout << "~D() "; } }; void test(B* ptr) { ptr->show(); } int main() { B * ptr = new D; test(ptr); delete ptr; }

    禁止重写的虚函数

    使用final关键字修饰的虚函数,派生类不可以对它进行重写,改变函数的定义或者行为;

    在派生类的过程中,final可以在继承关系链的中途设置,禁止后续派生类对指定虚函数的重写;

    class A

    {

    public:

      virtual void fun() = 0;

    };

    classB:public A

    {

      public:

        void fun() final;//到此为止,后续的子类不可以再重新写此接口函数

    };

    class C:public B

    {

      public:

        void fun();//无法通过编译

    };

    怕什么真理无穷,进一寸有一寸的欢喜。---胡适
  • 相关阅读:
    JavaScript面向对象精要(一)
    触摸事件
    移动端触摸事件介绍
    总结js常用函数和常用技巧(持续更新)
    JavaScript 常用函数总结
    windows环境下安装vue+webpack的开发环境
    js面向对象,多种创建对象方法!
    javascript遍历算法与技巧
    前端工作面试问题--摘取自github
    c++刷题(27/100)反转单项链表,链表的倒数第k个
  • 原文地址:https://www.cnblogs.com/hujianglang/p/6642606.html
Copyright © 2020-2023  润新知