C++学习笔记24,方法重写与方法隐藏


 

方法重写.是指在子类中重新编写父类中的虚函数的实现.要求子类中的函数必须跟父类中的原型一致.

包括返回值类型(协变返回类型不算)以及参数的数目,排列顺序.

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	virtual void show(int i,string s){
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}
};

int main(){
	base b;
	b.show(10,"base");
	dirved d;
	d.show(20,"dirved");
}

通过方法的重写,即可定义同一函数在继承层次中的不同行为!

如果在子类中使用父类虚方法的名称,但是参数不同,那么这个不是重写父类的方法,也不会重载方法,而是创建一个新方法.

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	/*
	virtual void show(int i,string s){
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}*/
	virtual void show(){
		cout<<"This is void dirved show!"<<endl;
	}
};

int main(){
	base b;
	b.show(10,"base");
	dirved d;
	//d.show(20,"dirved");
	d.show();
}


这个时候,父类中的show()方法将被隐藏,即dirved类中无法再使用show(int,string)方法.

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	/*
	virtual void show(int i,string s){
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}*/
	virtual void show(){
		cout<<"This is void dirved show!"<<endl;
	}
};

int main(){
	base b;
	b.show(10,"base");
	dirved d;
	d.show(20,"dirved");
	d.show();
}

编译结果:

可以看出,对于dirved类来说,show(int,string)这个方法被隐藏起来了,即对于dirved对象来说不可见了!因此只要在子类中重新定义了父类的虚方法,父类中的所有与该方法重载的方法都将被隐藏!

这一点需要特别注意!

下面再看一些有趣的东西:

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	virtual void show(int i,string s){
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}
};

int main(){

	dirved d;
	d.show(10,"show()");
	base &ref=d;
	ref.show(100,"ref show()");
}

子类中正确的重写了父类中的show方法,


结果没有疑问.但是如果你重写子类的show方法的时候,发现应该用double代替int,于是i更改为

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	virtual void show(double i,string s){
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}
};

int main(){

	dirved d;
	d.show(10,"show()");
	base &ref=d;
	ref.show(100,"ref show()");
}

运行结果:


看到没有!最后那个ref.show(int,string)调用了base里面的show方法!(100可以换成9.8更明显)

明明是dirved对象的引用,怎么就调用了base里面的show方法呢?因为这实际上是创建了一个新方法!

可用override关键字来避免这种情况!

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
};
class dirved:public base{
public:
	virtual void show(double i,string s)override{
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}
};

int main(){

	dirved d;
	d.show(10,"show()");
	base &ref=d;
	ref.show(95.9,"ref show()");
}


override表示你是想要重写base类的show方法而不是创建一个新的show方法,因此如果参数不对就会报错!

需要注意的是,即便是重写,只要在子类中重新定义了,父类中的相应重载函数都将会被隐藏!

如果不想既想使用父类中的show,又想重写某一个show(),可以利用using 

 

#include <iostream>
#include <string>
using namespace std;
class base{
public:
	virtual	void show(int i,string s){
		cout<<i<<"+"<<s<<endl;
		cout<<"This is base show!"<<endl;
	}
	virtual void show(){
		cout<<"this is a void show"<<endl;	
	}
};
class dirved:public base{
public:
	//using 
	using base::show;
	virtual void show(int i,string s)override{
		cout<<i<<"&"<<s<<endl;
		cout<<"This is dirved show!"<<endl;
	}
};

int main(){

	dirved d;
	d.show(10,"show()");
	base &ref=d;
	ref.show(95.9,"ref show()");
	d.show();
}

这样就两全其美啦!

——————————————————————————————————————————————————

//写的错误或者不好的地方请多多指导,可以在下面留言或者给我发邮件,指出我的错误以及不足,以便我修改,更好的分享给大家,谢谢。

转载请注明出处:https://www.royalchen.com/

author:royalchen

Email:royalchen@royalchen.com

———————————————————————————————————————————————————

 

 


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注