动态绑定与静态绑定的小结(改)
来源:互联网 发布:苹果软件资源共享 编辑:程序博客网 时间:2024/05/18 00:12
接下来的一段话是我从一位博客大佬那里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 0
- 动态绑定与静态绑定的小结(改)
- C++的静态绑定与动态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- c++的动态绑定与静态绑定
- java的动态绑定 与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- Java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- Linux安装git
- URAL 1123 Square Root(计算二次剩余)
- iOS 接入微信SDK报错 'NSInvalidArgumentException'
- ubuntu16 chrome download & install
- 二叉树反转java实现
- 动态绑定与静态绑定的小结(改)
- C语言:房贷计算器(等额本息与等额本金对比计算器)
- mysql学习4—插入、查询、删除
- 自动对齐的TextView 防止英文单词不能换行的问题
- 深入理解mysqldump原理 --single-transaction --lock-all-tables --master-data
- caioj1032· 递归2(组合)
- 记录一下平时遇到的乱七八糟的问题---需要不断更新
- javascript实现朴素贝叶斯分类与决策树ID3分类
- Hadoop基础教程-第11章 Hive:SQL on Hadoop(11.1 Hive 介绍)(草稿)