免费注册 查看新帖 |

Chinaunix

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

重载,覆盖,和隐藏 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-07 18:11 |只看该作者 |倒序浏览
这几个概念都有一个共同点:函数名称相同,所以不免让人混淆,大致的区别如下:

重载:必须在一个域中,函数名称相同但是函数参数不同,重载的作用就是同一个函数有不同的行为,因此不是在一个域中的函数是无法构成重载的,这个是重载的重要特征

覆盖:覆盖指的是派生类的虚拟函数覆盖了基类的同名且参数相同的函数,既然是和虚拟函数挂钩,说明了这个是一个多态支持的特性,所谓的覆盖指的是用基类对象的指针或者引用时访问虚拟函数的时候会根据实际的类型决定所调用的函数,因此此时派生类的成员函数可以"覆盖"掉基类的成员函数.
注意唯有同名且参数相同还有带有virtual关键字并且分别在派生类和基类的函数才能构成虚拟函数,这个也是派生类的重要特征.
而且,由于是和多态挂钩的,所以只有在使用类对象指针或者引用的时候才能使用上.
总之一句话:覆盖函数都是虚函数,反之不然~~

隐藏:指的是派生类的成员函数隐藏了基类函数的成员函数.隐藏一词可以这么理解:在调用一个类的成员函数的时候,编译器会沿着类的继承链逐级的向上查找函数的定义,如果找到了那么就停止查找了,所以如果一个派生类和一个基类都有同一个同名(暂且不论参数是否相同)的函数,而编译器最终选择了在派生类中的函数,那么我们就说这个派生类的成员函数"隐藏"了基类的成员函数,也就是说它阻止了编译器继续向上查找函数的定义....
回到隐藏的定义中,前面已经说了有virtual关键字并且分别位于派生类和基类的同名,同参数函数构成覆盖的关系,因此隐藏的关系只有如下的可能:
1)必须分别位于派生类和基类中
2)必须同名
3)参数不同的时候本身已经不构成覆盖关系了,所以此时是否是virtual函数已经不重要了
  当参数相同的时候就要看时候有virtual关键字了,有的话就是覆盖关系,没有的时候就是隐藏关系了


大致的区别和共同点就是这些.....我也是花了N长时间在血与泪的教训中总结出来的,说的不对的地方大家斧正~~

[ 本帖最后由 converse 于 2005-11-8 08:51 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2005-11-07 18:18 |只看该作者
慢慢消化

论坛徽章:
0
3 [报告]
发表于 2005-11-07 19:29 |只看该作者

  1. class foo
  2. {
  3. public:
  4.   void p(int i) { return; }
  5. };

  6. class bar
  7. {
  8. public:
  9.   void p(int l, int r) { return; }
  10. };
复制代码

好像有说, 这样子的话, 无论如何都不能

  1. bar b;
  2. b.p(19);
复制代码

会出错.

论坛徽章:
0
4 [报告]
发表于 2005-11-07 19:51 |只看该作者
倒...你这个是什么?既不是重载而且也不是派生类和基类的成员函数关系....有仔细看我写的东西么?

论坛徽章:
0
5 [报告]
发表于 2005-11-07 20:03 |只看该作者
顶一下

论坛徽章:
0
6 [报告]
发表于 2005-11-07 20:06 |只看该作者
o, sorry


class bar : public foo


  1. class foo
  2. {
  3. public:
  4.   void p(int i) { return; }
  5. };

  6. class bar : public foo
  7. {
  8. public:
  9.   void p(int l, int r) { return; }
  10. };

  11. int main()
  12. {
  13.   bar b;
  14.   b.p(15);  //似乎哪里看到这样子就要出错
  15.   return 0;
  16. }
复制代码

[ 本帖最后由 yarco1 于 2005-11-7 20:12 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2005-11-07 20:06 |只看该作者
原帖由 win_hate 于 2005-11-7 20:03 发表
顶一下


老兄好呀~~
北京快有暖气了吧,深圳还是一片艳阳天~~

论坛徽章:
0
8 [报告]
发表于 2005-11-07 20:07 |只看该作者
原帖由 yarco1 于 2005-11-7 20:06 发表
o, sorry


class bar : public foo


已经隐藏了foo里面的函数定义了,当然找不到foo里面的函数咯...
你还是好好看看我的文章吧....

论坛徽章:
0
9 [报告]
发表于 2005-11-07 20:12 |只看该作者
原帖由 converse 于 2005-11-7 20:06 发表


老兄好呀~~
北京快有暖气了吧,深圳还是一片艳阳天~~



这两天工人在拆洗暖气片呢........快有暖气了。

论坛徽章:
0
10 [报告]
发表于 2005-11-07 20:12 |只看该作者
隐藏:指的是派生类的成员函数隐藏了基类函数的成员函数.隐藏一词可以这么理解:在调用一个类的成员函数的时候,编译器会沿着类的继承链逐级的向上查找函数的定义,如果找到了那么就停止查找了,所以如果一个派生类和一个基类都有同一个同名(暂且不论参数是否相同)的函数,而编译器最终选择了在派生类中的函数,那么我们就说这个派生类的成员函数"隐藏"了基类的成员函数,也就是说它阻止了编译器继续向上查找函数的定义....
回到隐藏的定义中,前面已经说了有virtual关键字并且分别位于派生类和基类的同名,同参数函数构成覆盖的关系,因此隐藏的关系只有如下的可能:
1)必须分别位于派生类和基类中
2)必须同名
3)参数不同的时候本身已经不构成覆盖关系了,所以此时是否是virtual函数已经不重要了
  当参数相同的时候就要看时候有virtual关键字了,有的话就是覆盖关系,没有的时候就是隐藏关系了

老兄, 你有哪一句话说.
那种情况有怎样的结果.
在调用一个类的成员函数的时候,编译器会沿着类的继承链逐级的向上查找函数的定义

按照这句话理解.
bar b;
b.p(15);
应该会调用foo::p(int i)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP