C++ 重载 覆盖 隐藏 详细区分

重载:

重载在之前已经讲过,这里不在赘述详细的
link.
在同一个作用域下,函数名相同,参数列表不同即构成重载
条件:
必须在同一个作用域(类)下
函数名相同
参数列表不同: 参数类型和参数的个数不一样 对于指针和引用常属性不一样也构造重载
与返回值类型无关
与函数是否是虚函数无关
在编译时,根据调用时传递的实参类型和个数来绑定调用的函数,静态绑定

覆盖(重写):

说起覆盖先说一下虚函数

在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。
如果使用了virtual关键字,程序将根据引用或指针指向的 对 象 类 型 来选择方法,否则使用引用类型或指针类型来选择方法。

子类重写父类同型的虚函数
条件:
	分布在父子类中
	函数名相同
	参数列表必须相同:参数类型和个数必须相同 函数的常属性必须相同  参数是指针和引用 常属性也必须相同
	与返回值类型有关  如果不是类类型指针或者类类型引用,必须完全一致,否则可以有父子关系
	基类必须是虚函数  重写的版本也一定是虚函数
	在运行时,根据指针所指向的目标类型 或者 根据引用所引用的目标类型,来决定调用哪个版本的方法
	动态绑定  在运行时才决定调用哪个函数 
#include <iostream>
using namespace std;

class Shape{
private:
	double x;
	double y;
public:
	Shape(double x=0,double y=0):x(x),y(y){}
	virtual double len(){
		cout << "shape::len()" << endl;
		return 0.0;
	}
	virtual double area(){
		cout << "shape::area()" << endl;	
	}
	void draw(){
		cout << "shape::draw()   position:<" << x << "," << y << ")" << endl; 	
	}
	static Shape* maxArea(Shape* srr[],size_t size){
		Shape *pm = srr[0];
		for(int i=1;i<size;i++){
			cout << "-------------" << endl;
			if(srr[i]->area() > pm->area()){
				pm = srr[i];	
			}
		}
		return pm;
	}
};

class Rect:public Shape{
private:
	double l;
	double w;
public:
	Rect(double x,double y,double l,double w):Shape(x,y),l(l),w(w){
		
	}
	double len(){
		cout << "Rect::len()" << endl;
		return 2*(l+w);
	}
	double area(){
		cout << "Rect::area()" << endl;
		return l*w;
	}
};

class Circ:public Shape{
private:
	double r;
	static double PI;
public:
	Circ(double x,double y,double r):Shape(x,y),r(r){
		
	}
	double len(){
		cout << "Circ::len()" << endl;
		return PI*2*r;
	}
	double area(){
		cout << "Circ::area()" << endl;
		return PI*r*r;
	}
};

double Circ::PI = 3.14159;

int main(){
	Rect r(0,0,2,4);
	Circ c(0,0,3);

	cout << r.len() << endl;
	cout << c.len() << endl;
	cout << r.area() << endl;
	cout << c.area() << endl;


	Shape* ps = &r;
	ps->len();
	ps->area();

	ps = &c;
	ps->len();
	ps->area();

	Shape& rs = r;
	rs.len();
	rs.area();

	Shape& rc = c;
	rc.len();
	rc.area();



	Shape* arr[5] = {
		new Rect(0,0,4,1),new Circ(0,0,3),new Rect(0,0,3,3),
		new Circ(0,0,2),
		new Rect(0,0,2.5,4)
	};

	ps = Shape::maxArea(arr,5);

	cout << ps->area() << endl;
	return 0;	
}

隐藏:

子类隐藏父类同名的标识符(只讨论函数)
条件:
	分布在父子类中
	函数名相同
	如果参数不同,不管是否有virtual关键字,都构成隐藏
	如果参数一致,基类函数没有virtual关键字,构成隐藏,否则构成覆盖
#include <iostream>
using namespace std;

class A{};
class B:public A{};

class F{
public:	
	void f1(){
		cout << "F::f1()" << endl;	
	}
	void f1(int x){
		cout << "F::f1(int)" << endl;	
	}
	virtual void f2(){
		cout << "F::f2()" << endl;	
	}
	void f2(int x){
		cout << "F::f2()" << endl;	
	}
	virtual int f3(){
		
	}
	int f4(){
		
	}
	void f5()const{
		cout << "F::f5()const" << endl;		
	}
	virtual void f6(){
		cout << "F::f6()" << endl;	
	}
	virtual void f7(){
		cout << "F::f7()" << endl;	
	}
private:
	virtual void f8(){//子类不可见  子类依然可以覆盖
		cout << "F::f8()" << endl;	
	}
public:
	void bar(F *pf){
		pf->f8();//如果f8没有被覆盖 一定是调用父类的	
	}

	virtual A f9(){
		return A();	
	}

	virtual A* f10(){
		return new A();	
	}
	virtual A& f11(A& a){
		cout << "F::f11" << endl;
		return a;	
	}
	virtual void f12(int x){
		cout << "F::f12" << endl;	
	}
};


class S:public F{
public:
	void f1(){//隐藏  f1()   f1(int x)
		cout << "S::f1()" << endl;	
	}
	void f2(){//重写
		cout << "S::f2()" << endl;	
	}
	/*
	void f3(){//隐藏  覆盖  父类中的f3    虚函数+参数列表一致 覆盖 要求返回值类型
		
	}
	*/
	void f3(int){
		
	}
	virtual void f4(){//隐藏
		
	}
	void f5(){
		cout << "S::f5()" << endl;
	}
	void f6()const{//常属性不一致 不会构成覆盖
		cout << "S::f6()" << endl;	
	}
private:
	virtual void f7(){
		cout << "S::f7()" << endl;
	}
public:
	void f8(){
		cout << "S::f8()" << endl;	
	}
	/*
	B f9(){//函数名一样 参数列表一样  基类函数有virtual 返回值类型有要求
		return B();	
	}
	*/

	B* f10(){
		return new B();	
	}
	virtual B& f11(B& b){//隐藏
		cout << "S::f11(B& b)" << endl;	
		return b;
	}
	virtual B& f11(A& a){//覆盖
		cout << "S::f11(A& a)" << endl;
		return static_cast<B&>(a);
	}
	void f12(const int x){
		cout << "S::f12" << endl;
	}
};


int main(){
	S s;
	s.f1();
	s.F::f1();//通过显示的方式 访问 被隐藏的标识符

	s.F::f1(100);

	cout << "--------" << endl;
	s.f2();//重写
	s.F::f2();//被重写的方法也可以 显示 调用
	
	F *pf = &s;
	pf->f1(); //父类
	pf->f2(); //子类
	
	s.F::f2(100);//被子类同名的f2隐藏了
	
	s.f5();
	const S s1;
	//s1.f5();
	s.f6();
	pf->f6();
	pf->f7();//调用到了子类private方法
	//s.f7();
	//pf->f8();
	s.f8();
	pf->bar(pf);
	A a; B b;
	pf->f11(a);
	s.f11(b);
	pf->f11(b);
	s.f12(1);
	pf->f12(1);
	return 0;	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HOVL_C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值