免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2582 | 回复: 7
打印 上一主题 下一主题

[C++] 虚函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-22 16:41 |只看该作者 |倒序浏览
  1. class A
  2. {
  3. public:
  4.      void f( int a ){ cout << "A" << endl; };
  5. };
  6. class B : public A
  7. {
  8. public:
  9.     void f( int a ){ cout << "B" << endl; };
  10. };

  11. int main( int argc, char *argv[] )
  12. {
  13.     A *a = new A;
  14.     B *b = new B;
  15.     b->f(2);
  16.     a->f(2);
  17.     b =(B*)a;
  18.     b->f(2);
  19.     return 0;
  20. }
复制代码
输出为B A  B
  1. class A
  2. {
  3. public:
  4.     virtual void f( int a ){ cout << "A" << endl; };
  5. };
  6. class B : public A
  7. {
  8. public:
  9.     void f( int a ){ cout << "B" << endl; };
  10. };

  11. int main( int argc, char *argv[] )
  12. {
  13.     A *a = new A;
  14.     B *b = new B;
  15.     b->f(2);
  16.     a->f(2);
  17.     b =(B*)a;
  18.     b->f(2);
  19.     return 0;
  20. }
复制代码
输出为B A A
最后b = (B*)a,这句不知到咋理解?虚函数不管基类还是继承类,传入的是谁的对象,就调用谁的对应的虚函数?有点混,麻烦大家给指点一下

论坛徽章:
0
2 [报告]
发表于 2011-08-22 16:43 |只看该作者
来学习的,深了点,我不会。

论坛徽章:
0
3 [报告]
发表于 2011-08-22 18:33 |只看该作者
本帖最后由 pagx 于 2011-08-22 18:36 编辑

把基类对象强制转换为派生类,本来就是非法的,实际项目中也不会这么用,压根不不需要去讨论结果如何。
应该是把派生类转换为基类才是合法的,在这个例子里面程序没出错,但不代表在其他程序中不会出错。

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
4 [报告]
发表于 2011-08-22 19:24 |只看该作者
回复 1# kim1128


    http://blog.chinaunix.net/space. ... =blog&id=215380

我曾经专门写了篇文章阐述这个问题。LZ要是有耐心可以去看看。

文章中有一些谬误(比如C++标准绝对不可能规定虚函数表指针应该放在对象的那个位置),但是对于LZ的问题是完全可以回答的。因为许久没维护自己的blog,所以没改。还有文章比较长,可以无视函数重载解析的部分。另外,那个虚函数表描述的是单继承的简单情况。对于多继承来说,有多少个基类,就有多少个vptr. 而虚继承的情况又有所不同了。

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
5 [报告]
发表于 2011-08-22 19:36 |只看该作者
回复 1# kim1128


    你的第一段代码,叫做hide. 第二段代码,叫做override. 继承类的作用域处于基类作用域中.

    一般来说,是把指向继承类的指针转换为指向基类的指针。因为基类指针代表可以指向该继承体系的全部对象,只要是该继承体系实例化的东西,都可以看成 IS - A Base class 的实例. 想像,C++编译器在保证这一点时,那个多重继承和虚继承的情况是比较麻烦的...

论坛徽章:
0
6 [报告]
发表于 2011-08-22 21:00 |只看该作者
回复 4# captivated


    你博客的hide中例子好像是函数重载吧??不会出错的

论坛徽章:
0
7 [报告]
发表于 2011-08-22 21:39 |只看该作者
回复 3# pagx


    有道理,被各种破书折腾的啊!谢谢啊

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
8 [报告]
发表于 2011-08-24 09:41 |只看该作者
本帖最后由 captivated 于 2011-08-24 09:56 编辑

回复 6# kim1128


    那个例子是hide啊,怎么是函数重载了。特意在derived类中声明一个函数签名与基类中不同的成员函数,是为了说明,即使derived类中的函数与基类中的函数签名不一样,但只要函数名字相同,就会hide(人家还一直提醒说hide是作用域规则,而重载是必须要在处于同一作用域的前提条件下才能重载.派生类的作用域嵌套在基类之内,因此派生类不能直接重载基类的函数,要加using关键字。). 只要基类中没有声明virtual, hide就是一直发生的事情。
    什么是不会错的?...麻烦你好好看看我那贴。我那贴中是有不少错误,不过还不至于在这种简单问题上犯错。

    PS,所谓虚函数的多态,就是指声明一个基类的引用或者指针,传递什么(继承体系中的类)对象给它,它就调哪个(该对象真正的类的)函数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP