c++中的重载(Overload)、覆盖(重写,Override) 、隐藏与using声明
这些概念有时记住了,但可能没多久就忘了,还是记下来吧。网上找的一篇不错:这里
1 重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中,不包括继承来的);
(2)函数名字相同;
(3)参数不同;(包括const和非const,这里const既指形参,也指函数本身)
//《C++ primer》中提到“仅当形参是引用或指针的时候,形参是否为const才对重载有影响。”
void f(int a);
void f(const int a);//error:重复定义 //引用或指针所指为const时ok。指针常量不可以。
void f(int *p);
void f(const int *p);//ok
void f(int *const p);//error:重复定义 //调用含const形参引用的函数时,若实参类型与形参不匹配(如非const变量),将尽可能做类型转换,并产生临时变量存储实参转换后的值。并把形参作为该对象的引用!!-->c++11转移构造和转移赋值函数可解 -- 右值引用 因此下面均为重载:
class A
{
public:
void f(int *);
void f(const int *);
void f(int *) const;//因为隐含的this指针类型为const A*
};
(4)virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
令人迷惑的隐藏规则
本来仅仅区别重载与覆盖并不算困难,但是C++的隐藏规则使问题复杂性陡然增加。这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
例:
#include <iostream>
using namespace std; class Base
{
public:
virtual void vf(float x){ cout << "Base::f(float) " << x << endl; } void foo(){ cout << "Base::foo() " << endl; }
virtual void g(float x){ cout << "Base::g(float) " << x << endl; }
void h(float x){ cout << "Base::h(float) " << x << endl; }
}; class Derived : public Base
{
public:
virtual void vf(float x){ cout << "Derived::f(float) " << x << endl; } void foo(int x){ cout << "Base::foo() " << x << endl; }
void g(int x){ cout << "Derived::g(int) " << x << endl; } //隐藏-因为参数不同--即使基类函数是virtual
void h(float x){ cout << "Derived::h(float) " << x << endl; }//隐藏-即使参数相同,但非virtual
}; void main(void)
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// 多态 --- 取决于指向的对象类型
pb->vf(3.14f); // Derived::f(float) 3.14
pd->vf(3.14f); // Derived::f(float) 3.14 // 取决于指针类型
pb->foo(); //Base::foo()
//pd->foo(); //编译出错,派生类隐藏了Base::foo()
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 -->隐式转换 // 取决于指针类型
pb->h(3.14f); // Base::h(float) 3.14
pd->h(3.14f); // Derived::h(float) 3.14
}
上面的程序中:
(1)函数Derived::f(float)覆盖了Base::f(float)。
(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。
(3)函数Derived::h(float)隐藏了Base::h(float),而不是覆盖。
基类中被隐藏的函数可用作用域标识符直接调用,当然,在类外::只可访问public成员
pd->Base::foo();
pd->Base::g(3.14f);
pd->Base::h(3.14f);
当然,也可在类定义内部使用Base::foo();等等(派生类内(不管private继承还是protected继承)::可访问基类的public protected成员,但不能访问private函数)---这叫转发函数
也可以在派生类定义时使用using声明。
class Derived : public Base
{
public:
//让基类中所有名为 foo 和 g 的东西(如函数名 变量)在Derived的作用域中可见(并且是公有的)
using Base::foo;
using Base::g;
...
}
这样,之前对 pd->foo(); 等的调用都能成功
注意。不管如何继承,基类的私有成员都将在派生类中变的no access, using声明也无法使用基类的私有成员。关于继承级别和访问级别的权限控制,见这篇文章。
using的作用域问题与继承时访问标号的关系,可见:派生类中用using声明改变基类成员的访问权限
c++中的重载(Overload)、覆盖(重写,Override) 、隐藏与using声明的更多相关文章
- 重载(overload),覆盖/重写(override),隐藏(hide)
写正题之前,先给出几个关键字的中英文对照,重载(overload),覆盖/重写(override),隐藏(hide).在早期的C++书籍中,常常把重载(overload)和覆盖(override)搞错 ...
- 抽象方法(abstract method) 和 虚方法 (virtual method), 重载(overload) 和 重写(override)的区别于联系
1. 抽象方法 (abstract method) 在抽象类中,可以存在没有实现的方法,只是该方法必须声明为abstract抽象方法. 在继承此抽象类的类中,通过给方法加上override关键字来实现 ...
- 【Java】重载(Overload)与重写(Override)
方法的语法 修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; } 重载(overload) /** * 重载Overload: * 同一个类中,多个方法 ...
- Java方法多态性——方法的重载Overload和重写Override
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式. 重写(Override) 重写是 ...
- 重载overload 、重写override
观点:重载和重写完全没有关系要联系到一起,唯一的联系就是他们都带有个'重'字,所以鄙人也随大流把他们放在了一起 注意:下面可复制的代码是正确的,错误的只会上传图片,不上传可复制的代码 重载 1.在同一 ...
- Java面试 - 重载(Overload)和重写(Override)的区别?
1.重载是在同一个类中,可声明多个同名方法,但参数列表不同(参数顺序,个数,类型).而重写是在子类中,对从父类中继承的方法进行重新编写,但方法名,参数列表(参数顺序,个数,类型),返回值类型必须保持一 ...
- C++ 重载(overload)、重写(overrride)、重定义(redefine)总结
引自:http://www.189works.com/article-42111-1.html 先来看几个概念: 重载(overload),重写(override,也称覆盖), 重定义(redefin ...
- 方法的覆盖(override)、重载(overload)和重写(overwrite)
body { background-color: white } .markdown-body { min-width: 200px; max-width: 760px; margin: 0 auto ...
- JAVA中继承时方法的重载(overload)与重写/覆写(override)
JAVA继承时方法的重载(overload)与重写/覆写(override) 重载-Override 函数的方法参数个数或类型不一致,称为方法的重载. 从含义上说,只要求参数的个数或参数的类型不一致就 ...
- Delphi中静态方法重载还是覆盖的讨论
Delphi中静态方法重载还是覆盖的讨论 新人学习Delphi的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢? 答案是隐藏父类方法. 一般 ...
随机推荐
- 【Html 学习笔记】第二节——文本格式
上一节基本已经了解了一些html的基础,这一节主要学习html处理文本相关内容,直接看内容吧. 字体: 预格式文本:<pre> 地址:<address> 缩写:<abbr ...
- C++ 小工具一键解决SVN Clean Up 失败的问题
参考文章: 1.http://blog.csdn.net/luochao_tj/article/details/46358145 2.http://blog.csdn.net/segen_jaa/ar ...
- 点击链接跳转到固定div位置处(类似锚点链接)
$('.joinbtn').click(function(){ var a = $("#contact").offset().top;$("html,body" ...
- Python学习【第六篇】运算符
运算符 算数运算: a = 21 b = 10 c = 0 c = a + b print ("1 - c 的值为:", c) c = a - b print ("2 - ...
- Oracle同一数据库实例不同用户间的数据迁移
1.目标用户登录,创建自我连接的DB LINK -- Create database link create public database link MYLINK connect to 原用户名 u ...
- how-to-install-siege-on-centos-7
https://www.joedog.org/siege-home/ https://roastahost.com/how-to-install-siege-on-centos-7/ (Works!) ...
- iOS,非视图类方法
1.判断类的实例 2.获取当前最高层Window 3.获取当前app是否活跃 4.允许所有请求 5.判断设备是否越狱 6.移除字符串换行符和空格 7.iOS注释方法或属性废弃或不可用 8.本地通讯录操 ...
- SetSysColors 修改系统颜色
首先我们来看一下SetSysColors函数的原型: BOOL WINAPI SetSysColors( __in int cElements, //要改变的对象的数量 __in const INT* ...
- Cassandra 键空间(keyspace),表(table)
查看用户下信息: describe cluster; desc cluster; 查看所有keyspace: describe keyspaces; desc keyspaces; 查看key ...
- 索尼Sony ATI显卡驱动 Win7 Win8 Win8.1 视频黑屏 解决方法
索尼ATI显卡驱动 Win7 Win8 Win8.1 视频 黑屏 完美解决方法: 下载这个补丁 安装 即可 解决 ! baidu pan: http://pan.baidu.com/s/1gd ...