(原+转)继承与虚函数
参考网址:
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 阅读(189) 评论(0) 编辑 收藏 举报