动态绑定与静态绑定的小结(改)

接下来的一段话是我从一位博客大佬那里copy来的:

对象的静态类型:对象在声明时采用的类型。是在编译期确定的。
对象的动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

在此贴上大佬的文章:
(http://blog.csdn.net/chgaowei/article/details/6427731)
下面用c++primer第五版p550的代码说明一下:

#include <iostream>
using namespace std;
class Base{
public:
    virtual int fcn();
};
class D1:public Base{
public:
    //隐藏了基类的fcn,这个fcn不是虚函数
    //D1继承了Base::fcn()的定义
    int fcn(int);       //形参列表与Base中的fcn不一致
    virtual void f2();  //是一个新的虚函数,在Base中不存在
};
class D2:public D1{
public:
    int fcn();          //是一个非虚函数,隐藏了D1::fcn(int)
    int fcn(int);       //覆盖了Base的虚函数fcn
    void f2();          //覆盖了D1的虚函数f2
};
int main(){
    Base bobj;D1 dlobj;D2 d2obj;
    Base *bp1=&bobj,*bp2=&d1obj,*bp3=&d2obj;
    bp1->fcn();         //虚调用,将在运行时调用Base::fcn
    bp2->fcn();         //虚调用,将在运行时调用Base::fcn,因为D1中并没有fcn,编译器在Base中找到符合条件的fcn,于是调用Base的fcn
    bp3->fcn();         //虚调用,将在运行时调用D2::fcn,D2中存在fcn()
    return 0;
}

除了这些动态绑定,还有静态绑定,静态绑定是对于非虚函数的调用。调用的函数与对象的静态类型有关,最后一句也是摘自大佬的一句话:只有虚函数才使用的是动态绑定,其他的全部是静态绑定。目前我还没有发现不适用这句话的,如果有错误,希望你可以指出来。

//——————————————————
此处是我第二次增加的内容,内容是关于动态绑定中虚表和虚指针的状态和过程的图解和代码

#include<iostream>
using namespace std;
class base {
public:
    virtual void print() {
        cout << "base::print()" << endl;
    }
    virtual void goo() {
        cout << "base::goo()" << endl;
    }
};
class devired :public base {
public:
    virtual void print() {
        cout << "devired::print()" << endl;
    }
    virtual void go() {
        cout << "devired::go()" << endl;
    }
};
int main(void) {
    devired b;
    typedef void(*Fun)(void);
    Fun pfun = NULL;
    for (int i = 0; i < 3; i++)
    {
        pfun = (Fun)*((int*)*(int*)(&b)+i);
        pfun();
    }
    system("pause");
}

结果是:
devired::print()
base::goo()
devired::go()
可见devired::print()覆盖了base的print()这样也就实现了为什么能够多态了,用到的就是向上规则。还需要强调的是虚表是这几个类共享的。
下面摘自侯捷老师译注的《深度探索c++对象模型》:
注:代码是简易的,并没有完全实现的,另外图表不好画,就直接贴上了侯捷老师书上的截图

#include<iostream>
using namespace std;
class point {
public:
    virtual ~point() { cout << "~point()" << endl; }
    virtual point& mult(float) = 0;
    float x()const { return _x; }
    virtual float y()const { return 0; }
    virtual float z()const { return 0; }
protected:
    point(float x = 0.0) {};
    float _x;
};
class point2 :public point {
protected:
    float _y;
public:
    point2(float x = 0.0, float y = 0.0):point(x),_y(y){}
    ~point2() { cout << "~point2()" << endl; }
    point2& mult(float);
    float y()const { return _y; }
};
class point3 :public point2 {
protected:
    float _z;
public:
    point3(float x=0.0,float y=0.0,float z=0.0):point2(x,y),_z(z){}
    ~point3() { cout << "~point3()" << endl; }
    point3&mult(float);
    float z()const { return _z; }
};
void main(void) {

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值