1、重载(overload)
重载的定义为:在同一作用域中,同名函数的形式参数(参数个数、类型或者顺序)不同时,构成函数重载。例如:
class A
{
public:
int func(int a);
void func(int a, int b);
void func(int a, int b, int c);
int func(char* pstr, int a);
};
以上的四个函数均构成重载。
需要注意的是:
- 函数返回值类型与构成重载无任何关系
- 类的静态成员函数与普通成员函数可以形成重载
- 函数重载发生在同一作用域,如类成员函数之间的重载、全局函数之间的重载
对于重载,最出名的应该就是运算符重载了吧。
这里还需要注意一下 const重载:
class D
{
public:
void funcA(); //1
void funcA() const; //2
void funcB(int a); //3
void funcB(const int a); //4
};
在类D 中 funcA 与 const funcA是合法的重载,而 两个 funcB 函数是非法的,不能通过编译。
原因是:在类中,由于隐含的this形参的存在,const版本的function函数使得作为形参的this指针的类型变为指向const对象的指针,而非const版本的使得作为形参的this指针就是正常版本的指针。此处是发生重载的本质。
调用规则:const对象默认调用const成员函数,非const对象默认调用非const成员函数;
对于funcB,非引用传参,形参是否const是等价的。但是当使用引用传参时,有无const是不同的。使用指针传参时,指向const对象的指针和指向非const对象的指针做形参的函数是不同的。
2、隐藏(hiding)
隐藏定义:指不同作用域中定义的同名函数构成隐藏(不要求函数返回值和函数参数类型相同)。比如派生类成员函数隐藏与其同名的基类成员函数、类成员函数隐藏全局外部函数。
void hidefunc(char* pstr)
{
cout << "global function: " << pstr << endl;
}
class HideA
{
public:
void hidefunc()
{
cout << "HideA function" << endl;
}
void usehidefunc()
{
//隐藏外部函数hidefunc,使用外部函数时要加作用域
hidefunc();
::hidefunc("lvlv");
}
};
class HideB : public HideA
{
public:
void hidefunc()
{
cout << "HideB function" << endl;
}
void usehidefunc()
{
//隐藏基类函数hidefunc,使用外部函数时要加作用域
hidefunc();
HideA::hidefunc();
}
};
隐藏的实质是;在函数查找时,名字查找先于类型检查。如果派生类中成员和基类中的成员同名,就隐藏掉
3、重写/覆盖(override)
重写的定义:派生类中与基类同返回值类型、同名和同参数的虚函数重定义,构成虚函数覆盖,也叫虚函数重写。
需要注意的是,这里有一个特殊情况,即协变返回类型。
定义是:如果虚函数返回指针或者引用时(不包括value语义),子类中重写的函数返回的指针或者引用是父类中被重写函数所返回指针或引用的子类型。