演示代码:
#include<iostream>
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<iostream>
#include<cstring>
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<class t> 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<class t> 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