您的位置:首页 > 编程语言 > C语言/C++

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的起始位置

晚绑定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: