重载只要是涉及到函数,都可能存在,重写和重定义只有在涉及到继承才会出现。
目录
一、函数重载
1、函数重载的定义
在同一作用域内,两个同名函数的形参个数、类型、顺序至少要有一者不同,此时两个函数就构成重载。(与返回值无关)
2、构成函数重载的几种情况
判断是否构成函数重载的关键是,我们在调用这个函数的时候,不会存在歧义。
(1) 形参个数不同
void Func(int a) {
}
void Func(int a, int b) {
}
(2) 形参类型不完全相同
void Func(int a) {
}
void Func(double a) {
}
(3) 形参顺序不完全相同
形参顺序不完全相同的前提是,形参类型必须不同。
void Func(int a, double b) { // 站在编译器的角度: Func(int,double)
}
void Func(double a, int b) { // 站在编译器的角度: Func(double,int)
}
/*
如果两个形参都是 int 类型,实际在调用的时候, Func(1,1) 具体调用的是哪一个呢?
void Func(int a, int b) { // 站在编译器的角度: Func(int,int)
}
void Func(int b, int a) { // 站在编译器的角度: Func(int,int)
}
*/
3、不构成函数重载的几种场景
判断是否构成函数重载的关键是,我们在调用这个函数的时候,不会存在歧义。
(1) 使用了缺省值
void Func(int a) {
}
void Func(int a = 10) {
}
(2) 仅改变了返回值
void Func(int a) {
}
int Func(int a) {
}
二、重写(覆盖)
当一个类存在虚函数的时候,此时对象中除了包含自己声明的类成员外,还包含了虚表指针,这个指针指向了存放虚函数地址的一个表。子类在继承的时候,如果子类也有同名虚函数,此时就会覆盖继承父类的虚函数。(详细情况在多态的原理中介绍)
重写必须满足两个要求:
- 基类和派生类存在同名函数(必须同名、同形参、同返回值)
- 两个函数必须是虚函数
class Person
{
public:
virtual void BuyTicket() { cout << "全票" << endl; }
};
class Student:public Person
{
public:
virtual void BuyTicket() { cout << "半票" << endl; }
};
三、重定义(隐藏)
如果不构成重写,那就是重定义。“隐藏”指的是,父类和子类有两个同名函数,但是子类在继承的时候,父类的同名函数会被隐藏,子类访问该同名函数的时候默认访问的是子类的同名函数,如果要访问父类的同名函数,需要加上作用域。
重定义需要满足的条件是:两个同名函数分别在父类和子类的作用域
class Person
{
public:
void BuyTicket() { cout << "全票" << endl; }
};
class Student:public Person
{
public:
void BuyTicket() { cout << "半票" << endl; }
};
关于隐藏的具体介绍,可以链接直达 继承中的作用域