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的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢? 答案是隐藏父类方法. 一般 ...
随机推荐
- 使用dbghelp生成dump文件以及事后调试分析
前言 在产品的实际应用环境中,如果我们的程序在客户那里出现了问题,例如程序异常了,而这个时候的现象又不能还原或者很难还原重现,那么只有使用dump文件来保存程序的当前运行信息,例如调用堆栈等,同时使用 ...
- CentOS 下部署 ASP.NET Core环境
一.安装dotnet 1.下载运行环境 https://www.microsoft.com/net/download/linux 下载Runtime:https://go.microsoft.com/ ...
- C# 测试服务器连接 Ping
.aspx页: 一个textbox(txtIP)输入服务器地址,一个button(Btn_ok)点击测试,一个listbox(lboxContent)显示测试信息 .aspx.cs页: using S ...
- Redis性能测试
Redis 性能测试 Redis 性能测试是通过同时执行多个命令实现的.Redis性能测试主要是通过src文件夹下的redis-benchmark来实现(Linux系统下) 语法 redis 性能测试 ...
- jvm性能参数与调优
本文中的参数并齐全,看了http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html的相关文章写得很好,可以看一看 1.jvm堆内存简 ...
- java.lang.UnsupportedOperationException: Can't convert to dimension: type=0x12
最近使用Android Studio开发一个新项目,刚做完几个界面,跑在android 5.0上面很正常,因为都是挺简单的布局,本以为应该不存在兼容性问题(Flag啊). 偶然用了一个4.x的实机测试 ...
- Oracle同一数据库实例不同用户间的数据迁移
1.目标用户登录,创建自我连接的DB LINK -- Create database link create public database link MYLINK connect to 原用户名 u ...
- laravel5.1学习(1)--安装
主要学习的是laravel5.1版本,服务器用的是wampserver3.0.4集成环境: 首先,安装composer(windows系统) 下载地址:https://getcomposer.org/ ...
- Win7+Docker(boo2docker)搭建php开发环境简略
之所以称谓简略 是不准备配图的意思 嘿嘿! 步骤1: 到docker官网下载Docker Toolbox,并完全安装 步骤2: 安装完成后,运行在桌面新生成的快捷方式:Docker Quickstar ...
- UE4入门与精通
由于目前在使用UE4引擎,多少也有一些心得,比如在日常使用中会遇到一些问题.坑(潜规则)或者一些使用技巧等.本人决定开一个大坑,主要有两个目的:一是可以自己做个记录,二是可以给大家提供一些参考吧.主要 ...