zoukankan      html  css  js  c++  java
  • 浅谈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。

     

     
  • 相关阅读:
    asp.net实现页面的一般处理程序(CGI)学习笔记
    .NET下的状态(State)模式 行为型模式
    (插件Plugin)AssemblyLoader解决方案(插件开发)
    SQL基础编写基本的SQL SELECT 语句
    在查询语句中使用NOLOCK和READPAST(ZT)
    C# 3.0语言增强学习笔记(一)
    ram,rom,flash
    自动激活你的ActiveX控件
    用C#编写ActiveX控件(二)
    用C#编写ActiveX控件(一)
  • 原文地址:https://www.cnblogs.com/hojor/p/4424483.html
Copyright © 2011-2022 走看看