C++重载、覆盖与隐藏

重载

前提:(1)同一作用域
(2)函数名相同
要求:不同形参表
注:
返回类型和参数的缺省值不参与重载识别。函数前缀的访问控制(public/protected/private)不影响重载。在不同的名字空间声明的函数不是重载。除 main 函数之外的任何函数都可以重载。

重载的几种情况:
(1)
形参是引用,非引用时
void func(int &x);
void func(int x);
//不属于重载
(2)
形参是const引用,非const引用时
void func(const int &x);
void func(int &x);
//属于重载
(3)
形参是普通指针,指向常量的指针时
void func(int *p);
void func(int const *p);
//属于重载
(4)
形参是常指针,指向常量的指针时
void func(int const *p);
void func(int *const p);
//属于重载
(5)
形参是普通指针,指向常量的常指针时
void func(int *p);
void func(int const * const p);
//属于重载
(6)
形参使用了typedef,没有使用typedef时
typedefunsigned int UNIT
void func(UNIT b);
void func(unsigned int x);
//不属于重载

覆盖(重写)

特征:
(1)不同范围(分别位于基类跟派生类)
(2)函数名相同
(3)参数形同
(4)基类函数必须有 virtual 关键字
只对类的构造函数或者成员函数起作用,是子类继承父类才使用的非常有用的功能,真正和多态相关

注:重载可以针对运算符,而覆盖不行

例:
class Father
{
public:
void FunctionA() const
{
cout<<"This is FunctionA of class Father."<<endl;
}
virtual void FunctionB() const
{
cout<<"This is FunctionB of class Father"<<endl;
}
};
class Child : public Father
{
public:
void FunctionA() const
{
cout<<"This is FunctionA of class Child."<<endl;
}
virtual void FunctionB() const
{
cout<<"This is FunctionB of class Child"<<endl;
}
};

//在父类对象的指针指向子类对象时,Father *father = new Child; 如father->FunctionA(),则执行的是Father中的实现;father->FunctionB(),则执行的是Child中的实现
//如果直接声明子类对象,Child child; 则无论child.FunctionA()还是child.FunctionB(),执行的都是Child中的实现

隐藏

条件:
(1)派生类的函数与基类函数重名,但是参数不同,此时,无论有无关键字virtual,基类的函数将被隐藏(注意跟重载的区别,作用域)
(2)派生类的函数与基类函数重名,并且参数也相同,但是基类没有virtual关键字,此时,基类函数被隐藏(注意跟覆盖的区别,virtual关键字)


例子:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void f(float x){cout<<"Base::f(float)"<<x<<endl;}
void g(float x){cout<<"Base::g(float)"<<x<<endl;}
void h(float x){cout<<"Base::h(float)"<<x<<endl;}
};
class Derived:public Base
{
public:
virtual void f(float x){cout<<"Derived::f(float)"<<x<<endl;}
void g(int x){cout<<"Derived::g(int)"<<x<<endl;}
void h(float x){cout<<"Derived::h(float)"<<x<<endl;}
};
int main()
{
Derived d; //子类对象
Base *pb = &d; //父类指针指向子类对象
Derived *pd = &d; //子类指针指向子类对象
pb->f(3.14f); //覆盖,Derived::f(float) 3.14
pb->g(3.14f); //Base::g(float) 3.14 调用基类g(float)
pd->g(3.14f); //隐藏,Derived::g(float) 3
pd->h(3.14f); //隐藏,Derived::h(float) 3.14

return 0;
}



总结

(1)重载:发生在一个类中
(2)覆盖:发生在基类跟派生类之间,父类函数要加virtual,不然调用还是父类函数,并且是在父类指针指向子类对象时发生
(3)隐藏:发生在基类和派生类之间,但是基类函数没有virtual关键字,而且是在派生类指针指向派生类对象时发生
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值