• 浅谈C++的virtual 动态绑定。


    我们知道C++里 virtual函数可以用来实现多态。继承类可以实现自己的功能来覆盖基类。比如下面这段代码

    #include<iostream>
    #include<string>
    using namespace std;
    class BaseA{ 
    public:
        BaseA(string n):name(n){}
        string getName() const;
        virtual void showMyName() const;
        string name;
    };
    
    class DerivedA:public BaseA{
    public:
        DerivedA(string n):BaseA(n){}
        string getName() const;
        virtual void showMyName() const;
    };
    
    string BaseA::getName() const
    {
        cout<<"base static"<<endl;
        return name;
    }
    
    void BaseA::showMyName() const
    {
        cout<<"base:"<<name<<endl;
    }
    
    string DerivedA::getName() const
    {
        cout<<"derived static"<<endl;
        return name;
    }
    
    void DerivedA::showMyName() const
    {
        cout<<"derived:"<<name<<endl;
    }
    
    int 
    main()
    {
        DerivedA * derivedA = new DerivedA(string("abcd"));
    
        BaseA baseA = * derivedA; //会调用copy constructor函数
    
        baseA.showMyName();
        baseA.getName();
    
    
        BaseA * pBaseA = derivedA;
        pBaseA->showMyName();
        pBaseA->getName();
    
        return 0;
    }

    这段代码的输出:

    base:abcd
    base static
    derived:abcd
    base static

    我们来解读一下:

    BaseA baseA = * derivedA;  
    这里其实是构造了一个BaseA类,也就是构造了一个基类,虽然是右值是继承类。
    但这里会调用BaseA的default copy assignment函数,构造一个BaseA的实例。
    derivedA会被截断。
    那么当然了
      baseA.showMyName();
      baseA.getName();
    这俩行会调用BaseA的函数。

    我们再看一下下面这行
    BaseA * pBaseA = derivedA;
    这里声明了一个BaseA的指针 然后把指针指向派生类 DerivedA的一个实例。
    再看下面的代码
    pBaseA->showMyName(); pBaseA->getName();
    showMyName我们定义成了Virtual,也就是在内存里会有个函数指针,指向不同的实现。
    对于derivedA来说,这个函数的指针当然是指向DerivedA的showMyName。
    而pBaseA拿到的是derivedA的指针,那么当然调用的函数也会是DerivedA的实现函数。
    这个就是所谓的动态绑定。

    下面再看getName,相对于动态绑定函数,这是个静态函数,什么事静态函数呢,
    就是这个函数会根据对象的静态类型来调用。比如pBaseA的静态类型是BaseA,
    那么pBaseA所调用的就是BaseA的getName。

     

     
  • 相关阅读:
    FFmpeg在JAVA中的使用以及Process.waitFor()引发的阻塞问题
    分析自己遇到的Excel导出报NullpointException问题
    C# 获取文件路径
    List的方法和属性 方法或属性 作用
    asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    .NET 垃圾回收与内存泄漏
    .NET多线程总结和实例介绍
    C#中释放数据库连接资源
    PHP
    sqlconnection dispose()与close()的区别
  • 原文地址:https://www.cnblogs.com/hojor/p/4424483.html
Copyright © 2020-2023  润新知