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的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢? 答案是隐藏父类方法. 一般 ...
随机推荐
- composer install 卡壳
曾经用npm依赖包的时候也遇到了相应的问题,总而言之在国内,各种依赖包就换成国内的镜像吧你懂得! linux 或 window 命令行输入 composer config -g repo.packag ...
- Apache 配置多端口
Apache 配置多端口,主要是以下步骤 1. 如果电脑是64位的,官网上下载WampServe,装的过程中如果出现msvcp110.dll丢失的话,解决办法如下: 1.1 首先是打开浏览器,在浏览器 ...
- 弱网测试IOS
IOS测弱网非常方便,在设置-开发者-NETWORK LINK CONDITIONER的Status 进入后可以看到IOS自带了100%LOSS.3G.WiFi等常见场景 可以点击图标i进行查看或编辑 ...
- An error occurred while processing an SVN command
今天在使用SmartSVN的时候,遇到这个问题,反复几次,也没有得到解决,而且进入了死循环,一直在提示这个消息,即使在cleanup之后. 百度了一番之后,找到了解决办法: 把出错的文件在本地删除掉, ...
- Python开发【十一章】:数据库操作Memcache、Redis
一.Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的 ...
- 实时控制软件设计第一周作业-汽车ABS软件系统案例分析
汽车ABS软件系统案例分析 ABS 通过控制作用于车轮制动分泵上的制动管路压力,使汽车在紧急刹车时车轮不会抱死,这样就能使汽车在紧急制动时仍能保持较好的方向稳定性. ABS系统一般是在普通制动系统基础 ...
- 百度echarts
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>ECharts</t ...
- Url获取图片流并打包~
因为公司项目需求,做一个所有数据以excle的格式汇出,其中包括了图片. 而数据库保存的是图片的url,虽然不知道为什么....如果数据量大的话, 那么所有数据汇出,包括图片的话... 额.. 不知道 ...
- 200行代码搞定炸金花游戏(PHP版)
<?php/* * 游戏名称:炸金花(又名三张牌.扎金花) * 开发时间:2009.1.14 * 编 程:多菜鸟 * 来 源:http://blog.csdn.net/kingerq/archi ...
- ASCII码表(二进制 十进制 十六进制)
css里,允许使用转义字符\+ascii16进制形式; 例如: e的ascii 16进制是65,我们就写为\65 expression -> expr\65ssion 二进制 十进制 十六进制 ...