有关C++类中的重载,覆盖与隐藏

在过程式编程中,咱们经常用到重载,重载的好处显而易见,可让咱们以一个名字去定义某一类操做(对不一样的各类输入),其实在面向对象的类中,重载依然发挥这样的好处。编程

例如以下代码: class base { public: void checknum(int n){cout<<"this is a int num";} void checknum(float n){cout<<"this is a float num";}
}函数

int main() { int i = 5; float j = 5.6; base a; a.checknum(i); a.checknum(j); }this

当上述代码执行完毕,结果最终为 "this is a int num" "this is a float num"指针

注意:重载只在同一个类中产生效果,在同一类中定义某一种操做,属于编译器福利,重载成立的条件: 在同一个类中、函数名字相同、函数参数列表不一样(或是参数类型不一样,或是参数个数不一样)。另外还有注意一点,函数返回类型不构成重载,就好像:code

int check(int a){} float check(int a){}对象

这样的两个函数是不构成重载的。继承

重载说完,咱们说说覆盖的事,在面向对象的过程当中,类(即对某个对象特性的描述)是能够被继承的,就像编译器

卡车是汽车的一种,继承了汽车的特性,然而派生类也有本身的特色,不然咱们还用派生类做甚?(咱们用轿io

车拉货就行了,用卡车干甚?)由于拉货的属性是卡车所独有的,而对于特有的属性,须要有特有的操做,不编译

过这种操做每每只是通用状况的特例,(不管拉货仍是拉人,都只是拉这个操做的特例)因此咱们经常要对派

生类中的操做从新定义以适应当前的状况,这个时候,就用获得覆盖了。

覆盖,顾名思义,是对基类操做的覆盖。

例如以下代码:

class base
{
public:
virtual void check(int i){cout<<"this is base function";}
};

class derive :public base
{
public:
void check(int i){cout<<"this is derive function";}
};

当使用专门的对象调用本对象的操做时,一切都很天然,但咱们经常喜爱用一个指针指向某一个对象,指针是

万恶之源,尤为是当使用基类指针指向一个派生类对象时,会发生不少事情。

针对上面的代码,使用这样的main函数

int main()
{
    int i = 78;
    base *a = new derive();
    a->check(i);
}

当咱们执行完这个main函数,结果为:

this is derive function

假如把类derive中check函数的参数改为float i的话,结果就变成 this is base function 了,由此,我

们能够发现,其实覆盖只是另外一种形式的重载,是类间的重载,对于相同参数列表有效,能够执行不一样的操

做,可是,这仍是不够,咱们须要更加普遍的重载,即使对于不一样参数列表也有效,这就是以下的隐藏。

以代码举例:

class base
{
public:
void check(int i){cout<<"this is base function";}
};

class derive :public base
{
public:
void check(float i){cout<<"this is derive function";}
};

int main()
{
   
    int i = 78;
    base *a = new derive();
    a->check(i); 
}

最终结果为: this is base function

即使在base的check函数前加了virtual,结果仍是同样。

咱们进行最终总结:

重载:

1) 在同一类中;

2) 函数名字相同;

3) 参数不一样;

4) Virtual关键字无关紧要

覆盖:

1) 在不一样范围中(派生类与基类);

2) 函数名字相同;

3) 参数相同;

4) 必须有virtual关键字;

5) 若是函数返回值为引用或指针,能够修改成指向派生类的引用或指针

隐藏:

1) 范围不一样,函数名字相同,参数不一样,Virtual关键字无关紧要;

2) 范围不一样,函数名字相同,参数相同,基类无virtual关键字。

覆盖与隐藏运用中的区别:

覆盖:调用函数取决于指针或引用的对象的类型;

隐藏:调用函数取决于指针或引用的类型。

日常建议使用相应指针指向相应对象,假如必定要用基类指针指向派生类对象的话,请必定注意覆盖和隐藏的

有关事项,不然会有你想象不到的麻烦哦!