浅析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;

}
作者:Hello_Bugs原文地址:https://www.cnblogs.com/erichome/p/16929064.html

%s 个评论

要回复文章请先登录注册