34 虚函数与多态(一)
来源:互联网 发布:淘宝商品怎么上架视频 编辑:程序博客网 时间:2024/05/23 14:26
静态绑定与动态绑定
静态绑定
绑定过程出现在编译阶段,在编译期就已确定要调用的函数。
动态绑定
绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。
只有通过基类指针或引用调用虚函数才能引发动态绑定
#include <iostream>using namespace std;class Base{public: virtual void Fun1() { cout << "Base::Fun1 ..." << endl; } virtual void Fun2() { cout << "Base::Fun2 ..." << endl; } void Fun3() { cout << "Base::Fun3 ..." << endl; }};class Derived :public Base{public: /*virtual*/ void Fun1()//如果一个函数在基类中被声明为虚函数,则他在所有派生类中都是虚函数 { cout << "Derived::Fun1 ..." << endl; } /*virtual*/ void Fun2() { cout << "Derived::Fun2 ..." << endl; } void Fun3() { cout << "Derived::Fun3 ..." << endl; }};int main(void){ Base* p; Derived d; p = &d; p->Fun1(); //Fun1是虚函数,基类指针指向派生类对象,调用的是派生类对象的虚函数 p->Fun2(); p->Fun3(); //Fun3非虚函数,根据p指针实际类型来调用相应类的成员函数 return 0;}
#include <iostream>using namespace std;class Base{public: virtual void Fun1() { cout << "Base::Fun1 ..." << endl; } virtual void Fun2() { cout << "Base::Fun2 ..." << endl; } void Fun3() { cout << "Base::Fun3 ..." << endl; } Base() { cout << "Base ..." << endl; } //如果一个类要做为多态基类,要将析构函数定义成虚函数 virtual ~Base() { cout << "~Base ..." << endl; }};class Derived :public Base{public: /*virtual*/ void Fun1()//如果一个函数在基类中被声明为虚函数,则他在所有派生类中都是虚函数 { cout << "Derived::Fun1 ..." << endl; } /*virtual*/ void Fun2() { cout << "Derived::Fun2 ..." << endl; } void Fun3() { cout << "Derived::Fun3 ..." << endl; } Derived() { cout << "Derived ..." << endl; } ~Derived() { cout << "~Derived ..." << endl; }};int main(void){ Base* p; p = new Derived; p->Fun1(); delete p;//当通过基类指针删除派生类对象时,如果基类析构函数不是virtual,则派生类析构函数不会调用 return 0;}
虚表指针
虚函数的动态绑定是通过虚表指针来实现的
包含虚函数的类头4个字节存放指向虚表的指针
#include <iostream>using namespace std;class Base{public: virtual void Fun1() { cout << "Base::Fun1 ..." << endl; } virtual void Fun2() { cout << "Base::Fun2 ..." << endl; } int data1_;};class Derived :public Base{public: void Fun2() { cout << "Derived::Fun2 ..." << endl; } virtual void Fun3() { cout << "Derived::Fun3 ..." << endl; } int data2_;};typedef void(*FUNC)();int main(void){ cout << sizeof(Base) << endl; cout << sizeof(Derived) << endl; Base b; long** p = (long**)&b; FUNC fun = (FUNC)p[0][0]; fun(); fun = (FUNC)p[0][1]; fun(); cout << endl; Derived d; p = (long**)&d; fun = (FUNC)p[0][0]; fun(); fun = (FUNC)p[0][1]; fun(); fun = (FUNC)p[0][2]; fun(); return 0;}
object slicing与虚函数
#include <iostream>using namespace std;class CObject{public: virtual void Serialize() { cout << "CObject::Serialize ..." << endl; }};class CDocument : public CObject{public: int data1_; void func() { cout << "CDocument::func ..." << endl; Serialize(); } virtual void Serialize() { cout << "CDocument::Serialize ..." << endl; } CDocument() { cout << "CDocument" << endl; } CDocument(const CDocument& other) { cout << "CDocument(const CDocument& other)" << endl; }};class CMyDoc : public CDocument{public: int data2_; virtual void Serialize() { cout << "CMyDoc::Serialize ..." << endl; }};int main(){ CMyDoc mydoc; CMyDoc* pmydoc = new CMyDoc; cout << "#1 testing" << endl; mydoc.func(); cout << "#2 testing" << endl; ((CDocument*)(&mydoc))->func(); cout << "#3 testing" << endl; pmydoc->func(); cout << "#4 testing" << endl; ((CDocument)mydoc).func();//mydoc对象强制转换为CDocument对象,向上转型 //完完全全将派生类对象转化为了基类对象,调用拷贝构造函数 return 0;}
0 0
- 虚函数与多态(一)
- 34 虚函数与多态(一)
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图 .
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- c++多态性与虚函数(一)
- 单继承与虚函数表(虚函数一)
- 关于函数(一)const与函数
- Kotlin函数与Lambdas(一)--- 函数
- golang练习(一)循环与函数
- javascript基础一(变量与函数)
- Tensorflow常用基本概念与函数(一)
- 虚函数与多态(二)
- 多态与虚函数(虚表)
- c++的多态和虚函数(一)
- 函数调用约定与函数名称修饰规则(一)
- Ubuntu下mysql数据库的导入与导出命令
- algrothm_1000以内的(完数)
- 地理编码与反编码
- 双向链表
- JAVAFX 一点浅薄的学习建议
- 34 虚函数与多态(一)
- 简单选择排序
- openstack项目怎么进行单元测试
- 科目二考试技巧口诀
- SharedPreferences介绍与封装
- maven2不能下载jta-1.0.1B.jar的解决方法(手工安装):
- algrothm_最大公约数+最小公倍数?
- Merge k Sorted Lists
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解