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。

     

     
  • 相关阅读:
    NPM使用技巧
    重构老项目所悟
    Angular2开发笔记
    nodejs项目mysql使用sequelize支持存储emoji
    [原创]django+ldap+memcache实现单点登录+统一认证
    [原创]django+ldap实现单点登录(装饰器和缓存)
    [原创]django+ldap实现统一认证部分二(python-ldap实践)
    [原创]django+ldap实现统一认证部分一(django-auth-ldap实践)
    ldap部署相关,ldap双机LAM配置管理ldap备份还原
    通过pycharm使用git[图文详解]
  • 原文地址:https://www.cnblogs.com/hojor/p/4424483.html
Copyright © 2011-2022 走看看