这三个词分别描述了函数间的三种关系,要分清楚这三种关系,我们先来看一段代码示例:
#include <iostream>
class Base{
public:
void overload_func(){
std::cout<<"overload func without argumnet."<<std::endl;
}
void overload_func(int arg){
std::cout<<"overload func with with int argumnet "<<arg<<std::endl;
}
virtual void override_func(){
std::cout<<"override func Base"<<std::endl;
}
void overwrite_func(){
std::cout<<"over write func Base"<<std::endl;
}
};
class Derived:public Base{
public:
virtual void override_func(){
std::cout<<"override func Derived"<<std::endl;
}
void overwrite_func(){
std::cout<<"over write func Derived"<<std::endl;
}
};
int main()
{
Base base;
base.overload_func();
base.overload_func(1);
Base *pBase = new Base;
pBase->override_func();
pBase->overwrite_func();
pBase = new Derived;
pBase->override_func();
pBase->overwrite_func();
Derived derived;
derived.overwrite_func();
return 0;
}
上述代码的运行结果如下:
image.png
overload
先来说一下第一种关系,overload。下面的两个函数间的关系为overload:
void overload_func(){
std::cout<<"overload func without argumnet."<<std::endl;
}
void overload_func(int arg){
std::cout<<"overload func with with int argumnet "<<arg<<std::endl;
}
它们的区别在于参数是不一样的。同一个域内的同名函数,但是参数数量和参数类型是不一样的,这样的函数间的关系是overload。
这里需要说明的一点是,有cons
t修饰的函数和没有const
修饰的同名函数,也应该属于overload。
当编译器编译到overload函数时,它会根据函数的参数数量和参数类型找到合适的函数。由于不是每一个函数调用时都会使用到返回值,所以编译器在寻找适当的函数时,无法使用返回值的类型信息,这也是为啥返回值类型不用于区分overload函数。而不在同一个域内的同名函数,调用的时候会使用:: 操作符,这样就能直接匹配到对应的函数,不需要通过参数类型和参数数量来进行匹配。
函数重载意味着两个不同功能的函数使用着同样的名字。如果函数的区别没有小到只通过参数的类型和数量就能区分的话,我个人认为不应该使用函数重载,这样不是一个好的习惯。
override 和 overwrite
override和overwrite 应用在类的继承体系中,简单的来说就是我们在子类中实现了一个函数,该函数的原型同父类中的某个函数完全一致。这样,子类的函数就会将父类中的函数覆盖掉。
细心的同学会发现,我们对override_func
函数增加了virtual
指示符,而overwrite_func
却没有。这样导致的结果就是override可以使用多态,可以动态的找到合适的函数,而overwrite_func
却没有多态性质。
也就是说,在子类中,可以使用多态的函数重写可以理解为override,不能使用多态的函数重写为overwrite。再简单点就是,有没有virtual
指示符。
如果需要对父类中的函数进行重写,强烈建议添加virtual,不要overwrite。
C++ 11增加了override
关键字,强烈建议大家使用。
网友评论