首页 > 编程语言 >33.C++中的重载、重写(覆盖)和隐藏的区别

33.C++中的重载、重写(覆盖)和隐藏的区别

时间:2023-07-03 21:33:08浏览次数:48  
标签:函数 33 C++ fun int 基类 重载 重写

(1)重载(overload)

  重载是指在同一范围定义中的同名成员函数才存在重载关系。主要特点是函数名相同,参数类型和数目有所不同,不能出现参数个数和类型均相同,仅仅依靠返回值不同来区分的函数。重载和函数成员是否是虚函数无关。举个例子:

class A
{
    ...
    virtual int fun();
    void fun(int);
    void fun(double, double);
    static int fun(char);
    ...
}

(2)重写(覆盖)(override)

重写指的是在派生类中覆盖基类中的同名函数,重写就是重写函数体要求基类函数必须是虚函数且:

  • 与基类的虚函数有相同的参数个数
  • 与基类的虚函数有相同的参数类型
  • 与基类的虚函数有相同的返回值类型

举个例子:

//父类
class A{
public:
    virtual int fun(int a){}
}
//子类
class B : public A{
public:
    //重写,一般加override可以确保是重写父类的函数
    virtual int fun(int a) override{}
}

重载与重写的区别:

  • 重写是父类和子类之间的垂直关系,重载是不同函数之间的水平关系
  • 重写要求参数列表相同,重载则要求参数列表不同,返回值不要求
  • 重写关系中,调用方法根据对象类型决定,重载根据调用时实参表与形参表的对应关系来选择函数体

(3)隐藏(hide)

隐藏指的是某些情况下,派生类中的函数屏蔽了基类中的同名函数,包括以下情况:

  • 两个函数参数相同,但是基类函数不是虚函数。和重写的区别在于基类函数是否是虚函数。举个例子:
//父类
class A
{
public:
    void fun(int a)
    {
		cout << "A中的fun函数" << endl;
	}
};

//子类
class B : public A
{
public:
    //隐藏父类的fun函数
    void fun(int a)
    {
		cout << "B中的fun函数" << endl;
	}
};

int main()
{
    B b;
    b.fun(2); //调用的是B中的fun函数
    b.A::fun(2); //调用A中fun函数
    return 0;
}

隐藏和重写都是面向对象编程中的关键字,它们的区别在于:

1.参数列表不同:隐藏函数和被隐藏函数参数列表可以相同或不同,但函数名必须相同;而重写函数和被重写函数参数列表必须相同。

2.执行方式不同:隐藏函数会隐藏基类中的同名函数,而重写函数会覆盖基类中的同名函数。

  • 两个函数参数不同,无论基类函数是不是虚函数,都会被隐藏。和重载的区别在于两个函数不在同一个类中。举个例子:
//父类
class A
{
public:
    virtual void fun(int a)
    {
		cout << "A中的fun函数" << endl;
	}
};

//子类
class B : public A
{
public:
    //隐藏父类的fun函数
   virtual void fun(char* a)
   {
	   cout << "A中的fun函数" << endl;
   }
};

int main()
{
    B b;
    b.fun(2); //报错,调用的是B中的fun函数,参数类型不对
    b.A::fun(2); //调用A中fun函数
    return 0;
}

补充:

// 父类
class A
{
public:
    virtual void fun(int a) 
    { // 虚函数
        cout << "This is A fun " << a << endl;
    }  
    void add(int a, int b)
    {
        cout << "This is A add " << a + b << endl;
    }
};

// 子类
class B: public A
{
public:
    void fun(int a) override
    {  // 覆盖
        cout << "this is B fun " << a << endl;
    }
    void add(int a)
    {   // 隐藏
        cout << "This is B add " << a + a << endl;
    }
};

int main()
{
    // 基类指针指向派生类对象时,基类指针可以直接调用到派生类的覆盖函数,也可以通过 :: 调用到基类被覆盖
    // 的虚函数;而基类指针只能调用基类的被隐藏函数,无法识别派生类中的隐藏函数。

    A *p = new B();
    p->fun(1);      // 调用子类 fun 覆盖函数
    p->A::fun(1);   // 调用父类 fun
    p->add(1, 2);
    // p->add(1);      // 错误,识别的是 A 类中的 add 函数,参数不匹配
    // p->B::add(1);   // 错误,无法识别子类 add 函数
    return 0;
}

标签:函数,33,C++,fun,int,基类,重载,重写
From: https://www.cnblogs.com/codemagiciant/p/17524137.html

相关文章

  • 【C++】关于常引用的问题 #什么是权限放大?权限放小?隐式或强制转换居然还有这一步?...#
    前言引用在c++中的使用非常常见,可以说是很重要的,引用的常引用相关的问题让很多人稍不留神就出错了,这里我们就来谈谈常引用的问题。关于权限关于权限有权限缩小和权限放大的问题,比如一个文件,当初它只有读的权限,而现在你给它再加个写的权限,这就是权限放大;又或当初它读,写的权限......
  • 11.既然有了malloc-free,C++中为什么还需要new-delete呢?直接用malloc-free不好吗?
    malloc/free和new/delete都是用来申请内存和回收内存的。在对非基本数据类型的对象使用的时候,对象创建的时候还需要执行构造函数,销毁的时候要执行析构函数。而malloc/free是库函数,是已经编译的代码,所以不能把构造函数和析构函数的功能强加给malloc/free,所以new/delete是必不可少......
  • P3133 [USACO16JAN] Radio Contact G 无线电通话
    P3133[USACO16JAN]RadioContactG无线电通话目录P3133[USACO16JAN]RadioContactG无线电通话[USACO16JAN]RadioContactG题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示思路后记题目传送门[USACO16JAN]RadioContactG题目描述FarmerJohnhaslost......
  • C++学习笔记
    类型兼容不同类型的数据在一定条件下可以进行转换,比如intn='a',是将字符'a'赋值给整型变量n,在赋值过程中发生了隐式类型转换,字符类型的数据转换为整型数据。这种现象称为类型转换,也称为类型兼容。继承与派生继承方式public继承private继承protect继承类型兼容在C++中,基类与派生......
  • C++ 宏定义
    看到一段C++代码,大致是说如果如果定义了RUN_ALL_TESTS就执行下面的代码,遂研究了一下。#ifdefined(RUN_ALL_TESTS)//somecodehere#endif首先RUN_ALL_TESTS是定义的宏:#defineRUN_ALL_TESTS//空字符串#defineRUN_ALL_TESTS1//赋值为1#ifdefined......
  • Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
    有个需要是需要在安装包安装初始化时安装MicrosoftVisualc++2013Redistributable也就是判断软件安装前需不需要运行vcredist_x64.exe和VC_redist.x64.exe这两个程序第一反应就是可以通过注册表判断是否已经安装过环境但测试发现需求的两个版本不同,注册表位置竟然也不......
  • 《深入探索C++对象模型》- 第二章 - 构造函数语义学 - 笔记
    PDF版本https://www.aliyundrive.com/s/oQJJiJfQmU2......
  • C++面试记录——2023.7.3
    1、什么是虚函数?(基础反而卡住了,往多态方面说了)  2、虚函数实现原理?(不知道) 3、什么是完美转发?(没学深,浅浅说了跟右值引用相关) 4、构造函数有哪些?(默认、带参、拷贝、移动) 5、现有一个右值变量,如何调用移动构造函数?(麻了,不会) 6、知道lambda表达式吗?(C++11特性,匿......
  • c++实现多线程消息通信队列
    #ifndef_SYNC_SIMPLEQUEUE_QUEUE_HPP_#define_SYNC_SIMPLEQUEUE_QUEUE_HPP_#include<queue>usingnamespacestd;namespaceutility{template<typenameT>classSyncSimpleQueue{public:voidput(constT&msg){std::uniqu......
  • C++面试八股文:std::array如何实现编译器排序?
    C++面试八股文:std::array如何实现编译器排序?某日二师兄参加XXX科技公司的C++工程师开发岗位第25面:面试官:array熟悉吗?二师兄:你说的是原生数组还是std::array?面试官:你觉得两者有什么区别?二师兄:区别不是很大,原生数组(非动态数组)和std::array都在栈上开辟空间,初始化的时候......