C++函数重载、重写与重定义

演示代码:

#include
using namespace std;
class A {
public:
	virtual void Function(double i) {
		cout << "A: Function" << endl;
	}
	void Function1(int i, double d) {
		cout << "A: Function1" << endl;
	}
};
class B : public A {
public:
	//重载	和	重定义(隐藏)
	bool Function(int i) {
		cout << "B: Function(int)" << endl;
		return true;
	}
	//重写(也称为覆盖 override)
	void Function(double i) {					//若返回值不相同,则编译不通过
		cout << "B: Function(double)" << endl;
	}

	//重定义(隐藏)
	void Function1(double d) {
		cout << "B: Function1" << endl;
	}
};

int main() {
	B* bp = new B;
	bp->Function(4);				//B: Function(int)
	bp->Function(4.0);				//B : Function(double)
	bp->Function1(4.1);				//B: Function1
	A* bBp = bp;
	//bBp->Function1(4.1);				//编译出错,派生类重定义的函数Function1对该指针bp不可见
	//bp->Function1(1, 4.1);		//编译出错,因为基类函数被隐藏,无法调用
	return 0;
}

一、重载(overload)

在同一个作用域内,仅同名函数,但参数列(指参数的个数、类型或者顺序)必须不同,重载不关心函数返回类型。参数列表确定调用哪个函数。

1.匹配顺序
推荐相关文章:C++ 函数重载 指针类型匹配到bool类型

2.类的成员函数重载
除了拥有和一般全局函数重载的特性之外,const、volatile成员函数也构成重载
推荐相关文章:C++之const关键字的几种用法:八、2
C++中volatile限定符

3.模板函数重载
函数匹配规则:
1).对于一个调用,其候选函数包括所有模版实参推断成功的函数模版实例(顶层const可忽略;对于非引用的形参,数组或函数指针转化到到指针)

2).可行函数(模版和非模版),按类型转换排序

3).如果恰有一个函数比其它都更匹配,则选择此函数,否则
a.如果只有一个非模版函数,选择他
b.没有非模版函数,选择更特例化的模版
c.否则,有歧义,编译错误

#include
#include

using namespace std;

//相对的泛化
template<class t>
inline bool LESS(const t& t1, const t& t2)//本质上可用于任何类型,包括指针类型。 
{
	cout << "general   ";
	return t1 < t2 ? 1 : 0;
}
template<class t>//指针类型的重载版 ,只能用于指针类型,所以比上一个更特例化。 
inline bool LESS(t* const t1, t* const t2)
{
	cout << "overload1  ";
	return *t1 < *t2 ? 1 : 0;
}
template<class t>//const指针类型的重载版 ,只能用于const指针类型,所以比上一个更特例化。 
inline bool LESS(const t* const t1, const t* const t2)
{
	cout << "overload2  ";
	return *t1 < *t2 ? 1 : 0;
}

bool LESS(const char* const t1, const char* const t2)//普通函数版本,优先级更高 
{
	cout << "function  ";
	return strcmp(t1, t2);
}

template<>
inline bool LESS<char>(const char &t1, const char &t2)//全特化 template t LESS(const t& t1, const t& t2)
{
	cout << "special_one   ";
	return t1 < t2 ? 1 : 0;
}
template<>
inline bool LESS<const int*>(const int* const &t1, const int* const &t2)//全特化 template t LESS(const t& t1, const t& t2)
{
	cout << "special_two   ";
	return *t1 < *t2 ? 1 : 0;
}


template<class T1, class T2>
decltype(auto) Add(const T1 &t1, const T2 &t2)
{
	cout << "Add1   ";
	return t1 + t2;
}

template<class T1>
decltype(auto) Add(const T1 &t1, const T1 &t2)				//特化
{
	cout << "Add2   ";
	return t1 + t2;
}

template<class T2>
decltype(auto) Add(const int &t1, const T2 &t2)				//偏特化
{
	cout << "Add3   ";
	return t1 + t2;
}

int main()
{
	int int1 = 10;
	int int2 = 20;
	int* pint1 = &int1;
	int* pint2 = &int2;
	const int cint1 = 40;
	const int cint2 = 30;
	const int* cpint1 = &cint1;
	const int* cpint2 = &cint2;
	char c1 = 'a';
	char c2 = 'z';
	const char* const cc1 = "abc";
	const char* const cc2 = "abc";
	const int* const cpintc1 = &cint1;
	const int* const cpintc2 = &cint2;

	cout << LESS(int1, int2) << endl;						//general
	cout << LESS(pint1, pint2) << endl;						//overload1
	cout << LESS(cpint1, cpint2) << endl;					//overload2
	cout << LESS(cc1, cc2) << endl;							//function
	cout << LESS("hi", "zzzz") << endl;						//function
	cout << LESS(c1, c2) << endl;							//special_one 
	cout << LESS(cpintc1, cpintc2) << endl;					//overload2

	cout << Add(std::string("mai"), 'n').c_str() << endl;	//Add1   main
	cout << Add(1.002, 'c') << endl;						//Add1	100.002
	cout << Add(1.002, 2121.2) << endl;						//Add2   2122.2
	cout << Add(74, true) << endl;							//Add3   75
	//cout << Add(10, 87) << endl;							//Add2和Add3匹配二义性
}

疑问cout << LESS(cpintc1, cpintc2) << endl; //overload2

三、重写(也称为覆盖 override)

派生类中存在重新定义的函数。其函数签名(函数名,参数列表)和返回值类型都必须与基类中被重写的函数一致,并且基类中被重写的函数必须有virtual修饰,只有函数体不同(花括号内)。
1、基类对象调用基类被重写的函数。
2、派生类对象调用派生类重写的函数(重写、覆盖了基类函数)。
3、指向基类对象的基类指针调用基类被重写的函数(不表现多态)。
4、指向派生类对象的基类指针调用派生类重写的函数(多态性)。

二、重定义(隐藏)
1、派生类的函数重定义基类与其同名的函数。若基类为非虚函数,只要函数名称相同(不管参数列表是否相同);若基类为虚函数,参数列表则需不同(参数列、返回值相同则为重写;参数列相同、返回值不同编译不通过),基类函数都会被重定义(隐藏)。
1、基类对象调用基类被重定义的函数。
2、派生类对象调用派生类重定义的函数(基类函数被隐藏)。
3、指向基类对象的基类指针调用基类被重定义的函数(不表现多态)。
4、指向派生类对象的基类指针调用基类重定义的函数(派生类重定义的函数对该指针不可见)。

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

你可能感兴趣的:(C++基础,C++,Templates,c++,重载,重写,重定义,模板函数)