• 多态和虚函数


    在类的定义中,前面有virtual关键字的成员函数就是虚函数。多态是通过虚函数来实现的。

    Class base{

    Virtual int get();

    };

    Int base::get() { }

    • Virtual 关键字只用在类定义里的函数声明中,写函数体时不用。
    • 构造函数和静态成员函数不能是虚函数
    • 虚函数可以参与多态,而普通成员函数不可以。

     

    多态的变现形式之一

    • 派生类的指针可以赋给基类指针
    • 通过基类指针调用基类和派生类中的同名虚函数时:

    (1)若该指针指向一个基类的对象,那么被调用是基类的虚函数。

    (2)若该指针指向一个派生类的对象,那么被调用的是派生类的虚函数。

    这种机制就叫做多态。

    多态的表现形式二

    • 派生类的对象可以赋给基类引用
    • 通过基类引用调用基类和派生类中的同名虚函数时:

    (1)若该引用引用的是一个基类的对象,那么被调用的是基类的虚函数;

    (2)若该引用引用的是一个派生类的对象,那么被调用的是派生类的虚函数。

    这种机制也是多态。

    多态的作用

    在面向对象的程序设计中使用多态,能够增强程序的可扩充性,即程序需要修改或增加功能的时候,需要改动和增加的代码较少。

    多态的常用方法

    基类指针数组存放指向各种派生类对象的指针,然后遍历该数组,就能对各个派生类对象做各种操作,是很常用的做法。

    在非构造函数,非析构函数的成员函数中调用虚函数是多态。

    在构造函数和析构函数中调用虚函数不是多态,编译即可确定,调用的函数是自己的类或基类中定义的函数。

    派生类中和基类中虚函数同名同参数表的函数,不加virtual也自动成为虚函数。

    测试代码如下:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class A
    {
    private:
        int val;
    public:
        A(int val) :val(val) {};
        virtual void addVal()
        {
            val += 10;
            cout << "A::addVal() is called" << endl;
        }
        void print()
        {
            cout << val << " ";
            cout << "hello world!" << endl;
        }
    };
    
    class B :public A
    {
    private :
        string name;
        int value;
    public:
        B(string name, int value, int val) :A(val), name(name), value(value) {};
        virtual void addVal()
        {
            value += 50;
            cout << value << " ";
            cout << "B::addVal() is called" << endl;
        }
        void print()
        {
            cout << name << endl;
        }
        void printHH()
        {
            cout << "HH" << endl;
        }
    };
    
    int main()
    {
        A a(5); B b("chen", 8, 2);
        b.print();
        A & a1=b;
        a1.addVal();
        A *a2;
        a2 = &b;
        a2->addVal();
        a2->print();//调用的是基类中的print函数。原因是当基类和继承类中的函数名相同时,会优先调用自己类中的成员函数,a2是基类指针,属于基类因此会调用基类的成员函数。b.print()是调用继承类中的成员函数,因为b是继承类。
        return 0;
    }

     参考链接:

    https://www.coursera.org/learn/cpp-chengxu-sheji

     

  • 相关阅读:
    关于apicloud ios自定义模块引用第三方framework not found for architecture armv7
    C#实现生产消费者模式
    C# unity 的 IInterceptionBehavior实现aop拦截器
    递归算法,如何把list中父子类对象递归成树
    php后台权限管理
    php生成json或者xml数据
    PHP实现异步调用方法研究
    PHP判断请求是否是ajax请求
    PHP开发网站之微信登录、绑定
    Linux_10------Linux之shell编程------变量
  • 原文地址:https://www.cnblogs.com/helloforworld/p/5655281.html
Copyright © 2020-2023  润新知