浅析C++中的重载,隐藏和覆盖

 更新时间:2022年12月08日 11:21:33   作者:Hello_Bugs  
在C++语言中,函数扮演着很重要的角色,不管面向过程设计,还是基于对象设计。本文主要为大家介绍了函数中重载、覆盖和隐藏的相关知识,感兴趣的小伙伴可以了解一下

重载关系

一组函数要重载,必须处在同一个作用域中 ,而且函数名字相同,参数列表不同

代码1中的Base中的 show() 和show(int) 属于重载

代码2中的Base中的 show() 和Derive中的show()不属于重载不在同一个作用域下面

隐藏的关系(主要是指作用域隐藏)

在继承结构当中,派生类的同名成员,把基类的同名成员给隐藏掉了
例如代码2中的 Derive中的show() 和Base()中的show() ,show(int) 是隐藏关系

代码1

class Base
{
public:
	Base(int data=10):ma(data){
	   cout<<"Base"<<endl;
        }
	void show(){cout<<"Base Show()"<<endl;}
	void show(int){cout<<"Base Show(int)"<<endl;}
	~Base(){cout<<"~Base()"<<endl;}
protected:
	int ma;
};

class Derive : public Base
{
	public:
	Derive(int data=20):Base(data),mb(data){
	      cout<<"Derive"<<endl;
	}
        ~Derive(){cout<<"~Derive()"<<endl;}
	private:
        int mb;
};

int main(){

     Derive d(20); 
     d.show(); //正常调用基类show()
     d.show(100); //正常调用基类show(int)
     return 0;

}

代码2

class Base
{
public:
        Base(int data=10):ma(data){
	   cout<<"Base"<<endl;
        }
	void show(){cout<<"Base Show()"<<endl;}
	void show(int){cout<<"Base Show(int)"<<endl;}
	~Base(){cout<<"~Base()"<<endl;}
protected:
	int ma;
};

class Derive : public Base
{
	public:
	   Derive(int data=20):Base(data),mb(data){
	      cout<<"Derive"<<endl;
	   }
	void show(){cout<<"Derive Show()"<<endl;}
        ~Derive(){cout<<"~Derive()"<<endl;}
	private:
        int mb;
};

int main(){

     Derive d(20);
     d.show();   //调用子类show()
     d.show(100);//调用报错 报错信息 "Derive::show()函数不接受1个参数"
     // 即 Derive中的show()方法把Base中的show()和show(int)都给隐藏掉了
     // 所以d.show()没问题,调用的是派生类的show(),但是d.show(100)报错了,因为
     // 父类的show()和show(int)都被隐藏了,而派生类Derive中没有 show(int)方法所以报错了
     // 如果想调用父类的show(int) 要这样写 d.Base.show(100);
     return 0;

}

基类对象 -> 派生类对象

类型由上向下转 NOT OK

Base b(10);
Derive d(20);
d=b;// NOT OK

派生类对象 ->基类对象

类型由下向上转 OK

Base b(10);
Derive d(20);
b=d;//OK

派生类指针(引用) ->基类指针 类型由下向上转 OK

Base b(10);
Derive d(20);
Base *pb =&d;// OK 如下图, 基类指针只能访问到基类那一部分的成员,所以是安全的

代码3

class Base
{
public:
        Base(int data=10):ma(data){
	   cout<<"Base"<<endl;
        }
	void show(){cout<<"Base Show()"<<endl;}
	void show(int){cout<<"Base Show(int)"<<endl;}
	~Base(){cout<<"~Base()"<<endl;}
protected:
	int ma;
};

class Derive : public Base
{
     public:
	Derive(int data=20):Base(data),mb(data){
	      cout<<"Derive"<<endl;
	}
	void show(){cout<<"Derive Show()"<<endl;}
        ~Derive(){cout<<"~Derive()"<<endl;}
	private:
        int mb;
};

int main(){
Base   b(10);
Derive d(20);
Base  *pb =&d;
pb->show();    //调用的是基类的 show 
pb->show(100);//调用的是基类的 show(int)

((Derive *)pb)->show();    //强转后 调用的是派生类的 show 


}

基类指针(引用) -> 派生类对象 类型由上向下转 NOT OK

Base b(10);
Derive d(20);
Derive *pb =&b;// NOT OK pb指针能够访问的区域超过了实际对象b的内存块 ,危险访问

代码4

#include <iostream>
using namespace  std;

class Base{

public:
  Base(){
     cout<<"Base()"<<endl;
  }
  void show(){
     cout<<"Base show()"<<endl;
  }
  void show(int x){
     cout<<"Base show(int x)"<<endl;
  }
  ~Base(){
     cout<<"~Base()"<<endl;
  }

private:
     int ma;

};


class Derive :public Base{

public:
  Derive(){
     cout<<"Derive()"<<endl;
  }

  void show(){
     cout<<"Derive show()"<<endl;
  }

  ~Derive(){
     cout<<"~Derive()"<<endl;
  }

private:
     int ma;

};

int main(){

    Derive d;
    Derive *pd=&d;
    d.show();
    d.show(100);  //编译报错, Derive 的void show()方法把Base 的void show() void show(int x) 都隐藏了
    pd->show(100);//编译报错  Derive 的void show()方法把Base 的void show() void show(int x) 都隐藏了
    return 0;
}

代码5

#include <iostream>

using namespace  std;

class Base{

public:
  Base(){
     cout<<"Base()"<<endl;
  }

  virtual void show(){
     cout<<"Base show()"<<endl;
  }
  void show(int x){
     cout<<"Base show(int x)"<<endl;
  }
  ~Base(){
     cout<<"~Base()"<<endl;
  }

private:
     int ma;

};



class Derive :public Base{

public:
  Derive(){
     cout<<"Derive()"<<endl;
  }

  virtual void show(){
     cout<<"Derive show()"<<endl;
  }

  ~Derive(){
     cout<<"~Derive()"<<endl;
  }

private:
     int ma;

};



int main(){

    Derive *pd=new Derive();
    pd->show(100); //编译报错,Derive 中的show() 函数,只要名字与Base中有相同名字的函数的,就会隐藏掉Base中所有的show方法(不管加不加virtual),包括void show() void show(int x)

    return 0;

}

到此这篇关于浅析C++中的重载,隐藏和覆盖的文章就介绍到这了,更多相关C++重载 隐藏 覆盖内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 带你了解C++this指针的用法及其深究

    带你了解C++this指针的用法及其深究

    这篇文章主要介绍了C++中this指针的用法,对初学者而言是非常重要的概念,必须加以熟练掌握,需要的朋友可以参考下,希望能给你带来帮助
    2021-08-08
  • C++实现LeetCode(158.用Read4来读取N个字符之二 - 多次调用)

    C++实现LeetCode(158.用Read4来读取N个字符之二 - 多次调用)

    这篇文章主要介绍了C++实现LeetCode(158.用Read4来读取N个字符之二 - 多次调用),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 解读C++编程的相关文件操作

    解读C++编程的相关文件操作

    这篇文章主要介绍了解读C++编程的相关文件操作,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C语言修炼之路初识分支句 循环助本心上篇

    C语言修炼之路初识分支句 循环助本心上篇

    现实生活中我们经常需要根据不同的条件做出不同的选择。程序设计中也需要根据条件来选择不同的程序进行处理,这称之为分支结构,当条件表达式不存在时,它被假设为真。您也可以设置一个初始值和增量表达式,一般情况下,C 程序员偏向于使用 for(;;) 结构来表示一个无限循环
    2022-03-03
  • 深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下
    2013-05-05
  • C++利用stringstream进行数据类型转换实例

    C++利用stringstream进行数据类型转换实例

    这篇文章主要介绍了C++利用stringstream进行数据类型转换的方法,实例分析了使用stringstream进行string转int的操作技巧,需要的朋友可以参考下
    2015-01-01
  • cocos2dx实现刮奖效果

    cocos2dx实现刮奖效果

    这篇文章主要为大家详细介绍了cocos2dx实现刮奖效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Qt数据库应用之实现通用数据库分页

    Qt数据库应用之实现通用数据库分页

    数据库分页展示,在所有的涉及到数据库记录的项目中都是需要的。本文将利用Qt实现通用数据库的分页展示,感兴趣的小伙伴可以跟随小编学习一下
    2022-02-02
  • 详解C++中的const和constexpr

    详解C++中的const和constexpr

    这篇文章主要为大家介绍了C++中的const和constexpr ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++非继承时函数成员访问属性和类继承过程中的访问控制

    C++非继承时函数成员访问属性和类继承过程中的访问控制

    这篇文章主要介绍了C++非继承时函数成员访问属性和类继承过程中的访问控制,非继承时,protected成员和private成员没有任何区别,都是类内部可以直接访问它们、类外部的类对象不可访问它们、类内部的类对象可以访问它们,更多详细内容请参考下面相关资料
    2022-03-03

最新评论