重载(overload):在同一作用域中(同一个类中),或者在顶层函数(与main函数同层)中,如果(1)函数名字相同(2)函数参数列表不同就是函数重载。
注意:如果函数名相同,函数参数列表也相同,但函数返回值不同,这样的函数不能称之为重载。
下面代码中,两个function函数就是重载函数
class A
{
public:
void function(int);
void function(int,int);
};
但下面代码中,两个function函数就不是重载函数
class A
{
public:
int function(int);
void function(int);
};
覆盖(override):函数覆盖发生在继承层次之中。覆盖必须满足下面4个条件
(1)发生覆盖的函数必须分别在父类和子类中
(2)子类的成员函数的函数名与父类相同
(3)子类参数个数和类型与父类相同
(4)父类函数必须是虚函数
下面就是函数覆盖的一个例子,A类的指针指向B类的对象,调用的是B的函数。
class A
{
public:
virtual void function();
};
class B : public A
{
public:
void function();
};
int main()
{
A *p = new B;
p->function();
return 0;
}
注意:如果上面没有使用virtual关键字,那么调用的将是A函数。可见,函数覆盖可以实现多态调用。
隐藏(hide):指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
下面就是一个隐藏的例子:
class A
{
public:
void show() {}; //编号1
void rose(int a) {} //编号2
};
class B:public A
{
public:
void show() {}; //编号3
void rose(int a, int b) {}; //编号4
};
类B中的show()和rose()明显是隐藏了类A的show()和rose()
B类中其实有两个show(),两个rose();但为什么不叫重载呢?因为类B中的两个show(),两个rose(),不是都可以被类B对象调用的。
–>编号1和编号2,在类B中哪怕存在,但只能通过类A的指针调用,而不能通过B类对象调用,如:
A *p = new B;
p->show();
p->rose(3);
p->rose(3,5); //error
–>编号3和编程4,只能通过类B对象调用,而不能通过类A的指针调用,如:
B b;
b.show();
b.rose(3,5);
b.rose(4); //error
总结:
(1)函数重载发生在同一个类或顶层函数main中,同名的函数而具有不同的参数列表。
(2)函数覆盖发生在继承层次中,该函数在父类中必须是virtual,而子类的该函数必须与父类有相同的参数列表。
(3)函数隐藏(遮蔽)发生在继承层次中,父类和子类同名的函数中,不属于函数覆盖的都属于函数隐藏