虚函数

来源:互联网 发布:淘宝每天发货时间 编辑:程序博客网 时间:2024/05/17 04:54

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。


如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。 例virtual void print()=0;

class A{   
public:   
void print(){ cout<<"This is A"<<endl;}  
};  

class B:public A{   
public:   
void print(){ cout<<"This is B"<<endl;}   
};   

int main()
{
A a;   
B b;   
a.print();   
b.print();   
}   

输出
This is A
This is B

多态还有个关键之处就是用指向基类的指针或引用来操作对象(多态性是将接口与实现进行分离,单接口)

int main()
{   
A a;   
B b;   
A* p1=&a;   
A* p2=&b;  //由于是父子类 可以安全的传递指针 否则需要强转换 
p1->print();   
p2->print();   
}   

输出
This is A
This is A


以上代码改写一步: virtual void print(){ cout<<"This is A"<<endl;}  
输出
This is A
This is B

虚函数的实现

由于类中有虚函数存在,所以编译器就会为类插入一段数据,并创建一个表。

那段数据叫做vptr指针,指向那个表。那个表叫做vtbl,每个类都有自己的vtbl,vtbl的作用就是保存自己类中虚函数的地址,

分析下面的代码   
A *p=new A;   
p->print();   

首先是取出vptr的值,这个值就是vtbl的地址,再根据这个值来到vtbl这里,由于调用的函数A::print()是一个虚函数,所以取出vtbl里的值,这个值就是A::print()的地址了,最后调用这个函数。
现在我们可以看出来了,只要vptr不同(基类和派生类有不同的vptr),指向的vtbl就不同,而不同的vtbl里装着对应类的虚函数地址,所以这样虚函数就可以完成它的任务。
http://baike.baidu.com/view/161302.htm


虚基类

虚基类的基本原则是在内存中只有基类成员的一份拷贝。这样,通过把基类继承声明为虚拟的,就只能继承基类的一份拷贝,从而消除歧义。用virtual限定符把基类继承说明为虚拟的。
在派生类继承基类时,加上一个virtual关键词则为虚拟基类继承
虚基类主要解决在多重继承时,基类可能被多次继承,虚基类主要提供一个基类给派生类

原创粉丝点击