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

原创
2016/04/20 10:03
阅读数 175

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

例如如下代码: 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 is a int num" "this is a float num"

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

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

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

重载说完,我们说说覆盖的事,在面向对象的过程中,类(即对某个对象特性的描述)是可以被继承的,就像

卡车是汽车的一种,继承了汽车的特性,然而派生类也有自己的特点,否则我们还用派生类作甚?(我们用轿

车拉货就好了,用卡车干甚?)因为拉货的属性是卡车所独有的,而对于特有的属性,需要有特有的操作,不

过这种操作往往只是通用情况的特例,(无论拉货还是拉人,都只是拉这个操作的特例)所以我们常常要对派

生类中的操作重新定义以适应当前的情况,这个时候,就用得到覆盖了。

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

例如如下代码:

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关键字。

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

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

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

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

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

展开阅读全文
打赏
1
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部