码迷,mamicode.com
首页 > 编程语言 > 详细

C++虚函数

时间:2015-11-04 19:13:48      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:

C++

  在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。--(来至百度百科)

以下是定义的测试模型类:

技术分享
 1 class Base
 2 {
 3 public:
 4     virtual void print()
 5     {
 6         printf("Base print..\n");
 7     }
 8 
 9     void echo ()
10     {
11         printf("Base echo..\n");
12     }
13 
14     void doAction(int count)
15     {
16         printf("Base doAction:%d..\n",count);
17     }
18     ~ Base()
19     {
20         printf("Base: ~Base\n");
21     }
22 };
23 
24 class A:public Base
25 {
26 public:
27     void print()
28     {
29         printf("A print..\n");
30     }
31     
32     void echo ()
33     {
34         printf("A echo..\n");
35     }
36     
37     void doAction(int count)
38     {
39         printf("A doAction:%d..\n",count);
40     }
41     ~ A()
42     {
43         printf("A: ~A\n");
44     }
45 };
类定义

下面通过代码实例对多

 1 int main(int argc, const char * argv[]) {
 2     // insert code here...
 3     
 4     A var;
 5     Base *p = &var;
 6     A *q = &var;
 7     
 8     p->print();
 9     q->print();
10     p->echo();
11     q->echo();
12     
13     return 0;
14 }

输出如下:

1 A print..
2 A print..
3 Base echo..
4 A echo..

   父类Base中print()设置为虚函数,子类A同名同参数以及返回值的print()也默认为虚函数(virtaul void print(),这一步编译器自动帮我们做了),编译器为A和Base 分别建立了一张虚函数表,在函数调用时通过查这个表来获得函数的代码段地址,进而执行不同的功能。而两个类中的echo()是通过指针获得相对地址来直接执行相应的代码。

C++默认的“隐藏”功能,使得父类Base中的echo()被隐藏,子类A中echo()得到执行,请注意有别于override

另:析构函数往往也被定义为virtual

    

  以上呈现的是将子类强制转换成父类的情况,现在就看看将父类强制转换子类的情况。

 1     Base b;
 2     A *a = (A *)&b;
 3 
 4     a->print();//输出Base print..
 5     a->echo();//输出A echo..
 6     
 7 //对比
 8     A a0;
 9     Base *b0 = &a0;
10     b0->print();//输出A print..
11     b0->echo();//输出Base echo..

 

 

  这个输出结果可能跟预期的不一样,尤其是print()的输出。这就需要应用本文已开始提到的,虚函数的访问是以查虚表的形式来运行的,指针类型的转换,并不影响虚表指针

虚表的创建和虚表指针的初始化在构造函数中进行,然而本例中只调用了父类的构造函数,即只初始化父类的虚表,指针类型转化并未调用子类的构造函数。

 

参考:

1、虚函数、虚指针和虚表

2、虚函数

3、浅谈C++多态性

C++虚函数

标签:

原文地址:http://www.cnblogs.com/britphy/p/4936785.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!