c++_4: 多态_1_虚函数的定义
2015-12-09 11:19
369 查看
多态的概念
虚函数增强了类型的概念,而不是只是在结构内部隐藏代码;向上类型转换
函数调用的bangding
函数体和函数调用相联系称为捆绑早捆绑
晚捆绑:运行时发生的捆绑-动态捆绑
virtual函数
派生类的函数—–重写
//向上类型转换 #include <iostream> using namespace std; enum note { middleC,Csharp,Eflat }; //Etc. class Instrument { public: void play(note) const { cout<<"Instrument::play"<<endl; } }; class Wind:public Instrument { public: void play(note) const { cout<<"Wind::play"<<endl; } }; void tune(Instrument& i) { i.play(middleC); } int main() { Wind flute; tune(flute); //调用Instrument::paly//向上类型转换 }
添加虚函数
//向上类型转换 #include <iostream> using namespace std; enum note { middleC,Csharp,Eflat }; //Etc. class Instrument { public: virtaul void play(note) const // 虚函数 { cout<<"Instrument::play"<<endl; } }; class Wind:public Instrument { public: //Redefine interface function: void play(note) const { cout<<"Wind::play"<<endl; } }; void tune(Instrument& i) { i.play(middleC); } int main() { Wind flute; tune(flute); //调用Instrument::paly//向上类型转换 }
声明为虚函数后,调用Wind::play
虚函数
虚函数后,可以通过从公共基类继承新数据类型而增加新的功能#include <iostream> using namespace std; enum note { middleC, Csharp, Cflat }; // Etc. class Instrument { public: virtual void play(note) const { cout << "Instrument::play" << endl; } virtual char* what() const { return "Instrument"; } // Assume this will modify the object: virtual void adjust(int) {} }; class Wind : public Instrument { public: void play(note) const { cout << "Wind::play" << endl; } char* what() const { return "Wind"; } void adjust(int) {} }; class Percussion : public Instrument { public: void play(note) const { cout << "Percussion::play" << endl; } char* what() const { return "Percussion"; } void adjust(int) {} }; class Stringed : public Instrument { public: void play(note) const { cout << "Stringed::play" << endl; } char* what() const { return "Stringed"; } void adjust(int) {} }; class Brass : public Wind { public: void play(note) const { cout << "Brass::play" << endl; } char* what() const { return "Brass"; } }; class Woodwind : public Wind { public: void play(note) const { cout << "Woodwind::play" << endl; } char* what() const { return "Woodwind"; } }; // Identical function from before: void tune(Instrument& i) { // ... i.play(middleC); } // New function: void f(Instrument& i) { i.adjust(1); } // Upcasting during array initialization: Instrument* A[] = { new Wind, new Percussion, new Stringed, new Brass, }; int main() { Wind flute; Percussion drum; Stringed violin; Brass flugelhorn; Woodwind recorder; tune(flute); tune(drum); tune(violin); tune(flugelhorn); tune(recorder); f(flugelhorn); } ///:~
子类指针,指向派生类,通过调用派生类方法
虚函数的工作机制
/article/8189592.html为了达到晚绑定,编译器为每个包含虚函数的类创建一个虚函数表(VTABLE)
vpointer(VPTR)虚函数指针,多态时候,由基函数调用
过程:为类设置VTABLE->初始化VPTR(虚函数指针)->为虚函数插入调用代码
class NoVirtual { int a; public: void x() const{} int i() const {return 1;} }; class OneVirtual { int a; public: virtual void x() const{} int i() const {return 1;} }; class TwoVirtual { int a; public: virtual void x() const{} virtual int i() const {return 1;} };
sizeof(NoVirtual)=sizeof(int)
sizeof(onevirtual)=sizeof(novirtual)+sizoef(void)=在架构中插入一个单指针(VRTP)
sizeof(twovirtual)=sizeof(onevirtual)
虚函数的功能
虚函数表(参看c++编程思想p361)在类中插入VPTR(vpointer)
vpointer指向虚函数表(编译器为每个类创建虚函数表)
虚函数表中存放:子类的虚函数或者是派生类的函数地址
若派生类没有重新定义子类的虚函数,则存放基类的虚函数地址:Brass object
VPTR被初始化为虚函数表VTABLE的地址
基类调用虚函数地址
class Mammal { public: virtual speak(); move(); }; Class Dog : public Mammal { void speak(); void move(); }; int main() { Mammal *pDog=new Dog; pDog->Move(); // 调用Mammal的方法---Mammal::move pDog->speak(); //调用Dog的方法---Dog::speak---虚函数 }
vpoiter通常在对象的开头
取出vpointer
vpointer指向vtable的起始位置
晚绑定
相关文章推荐
- C++异常机制的实现方式和开销分析
- C++ 操作 MySQL
- C语言总结
- 【离散数学】实验四 图的随机生成及欧拉(回)路的确定
- 黑马程序员——C语言——文件读写
- 初来乍到之辛酸菜鸟
- 跟我一起玩Win32开发(1):关于C++的几个要点
- C语言结构类型
- Remove Element
- Remove Element
- 《C语言综合研究第2章宣讲会研究报告_20130610_v1.0》 2.docx
- 《C语言综合研究第1章宣讲会研究报告_20130609_v1.0》
- dev-c++ 添加boost库
- C++强大的背后(二)
- C++强大的背后(一)
- VC++中List Control控件的使用方法介绍
- C++11 元编程(meta-programming)判断T是否有==操作符
- C++下 VMP加壳宏
- 结构体总结
- 黑马程序员——C语言——typedef和#define