Overload(重载)
前面分析过C++函数重载是借助C++的name mangling 机制,允许在同一作用域中出现多个同名不同参的函数,如:
class Base{
int output(int a) {......};
int output(float b, float c){......};
};
这是重载,特点:
1) 同名不同参: 两个同名同参的函数绝不是重载,注意参数有无const也视为不同;
2) 仅仅返回值不同,不构成重载;
3) 相同的作用域:同一文件域/全局域/namespace域内的同名不同参函数可以构成重载;而对于类成员函数,重载必须发生在同一类域中,分属于基类与派生类的函数不能直接构成重载(派生类函数重载基类函数的说法错误)。
Override(覆盖)
在派生类中重新定义实现基类中的虚函数,这个过程就是override(译为覆盖),如:
class Base{
virtual void output() { cout << "Base::output" << endl; }
};
class Drv0:public Base{
void output() { cout << "Drv0::output" << endl; }
};
这里Drv0::output就是覆盖(override)了Base::output,覆盖的特征:
1) 不同的作用域(分别位于派生类与基类);
2) 基类函数必须为virtual函数,而派生类重新实现的函数需与基类虚函数同名同参。
Overwrite(重写)
指派生类的函数屏蔽与其同名的基类函数,发生在不同类域(派生类与基类之间),具体情形包括:
1) 派生类与基类同名但不同参,此时无论基类函数是否是virtual,其都将被派生类函数重写;
2) 派生类函数与基类非virtual函数同名同参,此时基类函数被重写;
梳理后的逻辑: 类public派生时,基类成员全部继承到派生类,除非派生类有同名;当派生类与基类成员有同名,除了基类成员为virtual函数时属于覆盖(override),其他情况都是重写。
区分:
1) overload 原理上与override/overwrite没有实质性的关联和相似,overload是同一类中的成员函数间的水平关系;而override/overwrite都是派生类和基类间的垂直关系,只要设计到派生类/基类间的关系就不可能是overload。
2) override覆盖的前提或特点是基类函数必须为virtual,派生类中同名同参重新实现基类的virtual函数就是override,覆盖后可通过基类指针指向的具体对象类型确定调用哪个方法,从而实现函数多态;而overwrite是指派生类的函数屏蔽与其同名的基类非virtual函数,使其不能被派生类对象直接引用。