这些概念有时记住了,但可能没多久就忘了,还是记下来吧。网上找的一篇不错:这里

 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声明的更多相关文章

  1. 重载(overload),覆盖/重写(override),隐藏(hide)

    写正题之前,先给出几个关键字的中英文对照,重载(overload),覆盖/重写(override),隐藏(hide).在早期的C++书籍中,常常把重载(overload)和覆盖(override)搞错 ...

  2. 抽象方法(abstract method) 和 虚方法 (virtual method), 重载(overload) 和 重写(override)的区别于联系

    1. 抽象方法 (abstract method) 在抽象类中,可以存在没有实现的方法,只是该方法必须声明为abstract抽象方法. 在继承此抽象类的类中,通过给方法加上override关键字来实现 ...

  3. 【Java】重载(Overload)与重写(Override)

    方法的语法 修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; } 重载(overload) /** * 重载Overload: * 同一个类中,多个方法 ...

  4. Java方法多态性——方法的重载Overload和重写Override

    方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式. 重写(Override) 重写是 ...

  5. 重载overload 、重写override

    观点:重载和重写完全没有关系要联系到一起,唯一的联系就是他们都带有个'重'字,所以鄙人也随大流把他们放在了一起 注意:下面可复制的代码是正确的,错误的只会上传图片,不上传可复制的代码 重载 1.在同一 ...

  6. Java面试 - 重载(Overload)和重写(Override)的区别?

    1.重载是在同一个类中,可声明多个同名方法,但参数列表不同(参数顺序,个数,类型).而重写是在子类中,对从父类中继承的方法进行重新编写,但方法名,参数列表(参数顺序,个数,类型),返回值类型必须保持一 ...

  7. C++ 重载(overload)、重写(overrride)、重定义(redefine)总结

    引自:http://www.189works.com/article-42111-1.html 先来看几个概念: 重载(overload),重写(override,也称覆盖), 重定义(redefin ...

  8. 方法的覆盖(override)、重载(overload)和重写(overwrite)

    body { background-color: white } .markdown-body { min-width: 200px; max-width: 760px; margin: 0 auto ...

  9. JAVA中继承时方法的重载(overload)与重写/覆写(override)

    JAVA继承时方法的重载(overload)与重写/覆写(override) 重载-Override 函数的方法参数个数或类型不一致,称为方法的重载. 从含义上说,只要求参数的个数或参数的类型不一致就 ...

  10. Delphi中静态方法重载还是覆盖的讨论

    Delphi中静态方法重载还是覆盖的讨论 新人学习Delphi的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢? 答案是隐藏父类方法. 一般 ...

随机推荐

  1. spring_异常提示1

    nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource ------- 缺少j ...

  2. leetcode 383. Ransom Note

    
Given
 an 
arbitrary
 ransom
 note
 string 
and 
another 
string 
containing 
letters from
 all 
th ...

  3. WP8.1 侧边滑动Item

    效果图 我看ios 和安卓上有好多类似的Item的效果,UWP上有微软官方的库,其中也有类似得效果,看样子WP8.1没有啊,顺便我的程序也是需要,我也就仿了一个. 具体思路是: 触摸控制GRId在CA ...

  4. JavaScript增强AJAX基础

    <title>js类型</title> <meta http-equiv="content-type" content="text/html ...

  5. docker 使用非加密registry

    配置docker成为服务,自启动 sudo systemctl enable docker.service 启动服务 sudo systemctl start docker docker默认要求我们使 ...

  6. 跟着思维导图学习javascript

    1.javascript 变量 2.javascript 运算符 3.javascript 数组 4.javascript 流程语句 5.javascript字符串函数 6.javascript 函数 ...

  7. RDIFramework.NET-.NET快速信息化系统开发整合框架 【开发实例 EasyUI】之产品管理(MVC版)

    RDIFramework.NET—.NET快速开发整合框架 [开发实例]之产品管理(MVC版) 接上篇:RDIFramework.NET (.NET快速信息化系统开发整合框架) [开发实例]之产品管理 ...

  8. ferret32位安装

    首先在网上找到解决方案: 1.添加对32位的支持 dpkg --add-architecture i386 2.更新 apt-get clean && apt-get update & ...

  9. hduoj 1251 统计难题

    http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory ...

  10. 最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布

    最新IP地址数据库  来自 qqzeng.com 利用二分逼近法(bisection method) ,每秒300多万, 比较高效! 原来的顺序查找算法 效率比较低 readonly string i ...