(原+转)继承与虚函数

参考网址:

http://blog.csdn.net/hackbuteer1/article/details/7475622

http://blog.csdn.net/j123kaishichufa/article/details/9841261

如下代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class A
 5 {
 6 public:
 7     void foo()
 8     {
 9         printf("1\n");
10     }
11     virtual void fun()
12     {
13         printf("2\n");
14     }
15 };
16 class B : public A
17 {
18 public:
19     void foo()
20     {
21         printf("3\n");
22     }
23     void fun()
24     {
25         printf("4\n");
26     }
27 };
28 
29 int _tmain(int argc, _TCHAR* argv[])
30 {
31     A a;
32     B b;
33 
34     A *p = &a;
35     p->foo();
36     p->fun();
37     p = &b;
38     p->foo();
39     p->fun();
40 
41     B *ptr = (B *)&a;
42     ptr->foo();
43     ptr->fun();
44 
45     return 0;
46 }

在VS2013上结果如下:

1
2
1
4
3
2

解释:

   在继承层次中,存在向上指针类型转换或者向下类型转换,则调用成员函数(两个类都实现了)调用的是哪个类的函数,遵循下面2个规则:

1)调用虚函数时,因为是动态绑定,所以根据指针指向的对象的实际类型来决定。

2)调用非虚函数,静态决定,所以根据表面山看到的类的类型来决定。

下面是另一个例子,白天没看明白,现在仔细看了一下,明白了。

 1 class A
 2 {
 3 public:
 4     void virtual f()
 5     {
 6         cout << "A" << endl;
 7     }
 8 };
 9 
10 class B:public A
11 {
12 public:
13     void virtual f()
14     {
15         cout << "B" << endl;
16     }
17 };
18 
19 int _tmain(int argc, _TCHAR* argv[])
20 {
21     A *pa=new A; 
22     pa->f();        // 1
23     B* pb = (B*)pa;
24     pb->f();        // 2
25     delete pa, pb;
26 
27     pa = new B;
28     pa->f();        // 3
29     pb = (B*)pa;
30     pb->f();        // 4
31     delete pa, pb;
32 
33     return 0;
34 }

输出的结果是:

A
A
B
B

1和2都好理解,按照第一条,由于都是调用虚函数,因而根据指针指向的对象的类型判断调用的函数。

3也好理解,4开始没明白。看的时候,感觉pb是指向pa的,由于没仔细看,以为pa还是指向A的,感觉应该输出A才对,不明白为什么输出B。刚才又仔细看了一下,其实3句已经将pa指向B了,所以pb最终还是指向B的。因而输出B。

其实仔细看的话,根据上面红色加粗的字体(第二个参考网址给出的)可以很好地判断出来(当然要仔细),同时也就不用考虑书中总写着覆盖不覆盖的问题了。

 

posted on 2015-03-31 10:14  darkknightzh  阅读(186)  评论(0编辑  收藏  举报

导航