C++-重载、隐藏、覆盖
本章记录c++重载、隐藏、覆盖的概念与测试。
1. C++重载
- 重载是学习c++最开始接触的,也是比较容易理解,不过如果没注意关键特点,也有可能与后面两个概念混淆。
- 特点:
- 函数名相同,参数不同;
在同一个作用域内,比如同个类中
;- 可以没有virtual关键字;
重载最为常见也是最为简单,比如运算符重载,这里不进行演示。
2. 隐藏
- 隐藏指派生类得函数屏蔽了预期同名的基类函数。规则如下:
- 如果派生类的函数与基类同名,但是参数不同。此时,不论有无virtual关键字,基类的函数都将被隐藏(注意与重载区分)。
- 如果派生类函数与基类函数同名且参数相同,但是没有virtual关键字,此时基类函数被隐藏。
3. 覆盖
- 覆盖指派生类覆盖基类同名函数,与隐藏的区别是:不论是父类指针还是子类指针,指向子类对象,都只会调用覆盖后的子类函数。规则如下:
- 同样是基于子类和父类;
- 函数名相同,参数相同;
- 基类函数必须有virtual关键字修饰。
4. 隐藏与覆盖的区别实例
隐藏:如果使用父类的指针指向子类对象Base *pb = &derived ,此时会调用父类的同名函数;如果是子类指针指向子类对象,Derived *pd = &derived , 此时调用子类的同名函数。
覆盖:不管是父类指针还是子类指针,指向子类对象时,对于同名函数直接调用,只调用子类的函数,这就是覆盖。(除非是通过Base::f(float)调用方式,则会锁定得调用父类同名函数)
测试代码如下:
#include <iostream>
using namespace std;class Base{public:virtual void f(float x) {cout << "Base::f(float)" << x << endl;};virtual void g(float x) {cout << "Base::g(float)" << x << endl ;};void h(float x) {cout << "Base::g(float)" << x << endl ; };
};class Derived : public Base{public : virtual void f(float x) {cout << "Derived::f(float)" << x << endl;};virtual void g(int x) {cout << "Derived::g(int)" << x << endl ;};void h(float x) {cout << "Derived::g(float)" << x << endl ; };
};int main(void ){Derived d;Base *pb = &d; // 父类指针指向子类对象Derived *pd = &d; // 子类指针指向子类对象 pb->f(3.14f); pd->f(3.14f); pd->Base::f(3.14f);pb->g(3.14f);pd->g(3.14f);pb->h(3.14f);pd->h(3.14f);return 0;}
结果:
C++-重载、隐藏、覆盖
本章记录c++重载、隐藏、覆盖的概念与测试。
1. C++重载
- 重载是学习c++最开始接触的,也是比较容易理解,不过如果没注意关键特点,也有可能与后面两个概念混淆。
- 特点:
- 函数名相同,参数不同;
在同一个作用域内,比如同个类中
;- 可以没有virtual关键字;
重载最为常见也是最为简单,比如运算符重载,这里不进行演示。
2. 隐藏
- 隐藏指派生类得函数屏蔽了预期同名的基类函数。规则如下:
- 如果派生类的函数与基类同名,但是参数不同。此时,不论有无virtual关键字,基类的函数都将被隐藏(注意与重载区分)。
- 如果派生类函数与基类函数同名且参数相同,但是没有virtual关键字,此时基类函数被隐藏。
3. 覆盖
- 覆盖指派生类覆盖基类同名函数,与隐藏的区别是:不论是父类指针还是子类指针,指向子类对象,都只会调用覆盖后的子类函数。规则如下:
- 同样是基于子类和父类;
- 函数名相同,参数相同;
- 基类函数必须有virtual关键字修饰。
4. 隐藏与覆盖的区别实例
隐藏:如果使用父类的指针指向子类对象Base *pb = &derived ,此时会调用父类的同名函数;如果是子类指针指向子类对象,Derived *pd = &derived , 此时调用子类的同名函数。
覆盖:不管是父类指针还是子类指针,指向子类对象时,对于同名函数直接调用,只调用子类的函数,这就是覆盖。(除非是通过Base::f(float)调用方式,则会锁定得调用父类同名函数)
测试代码如下:
#include <iostream>
using namespace std;class Base{public:virtual void f(float x) {cout << "Base::f(float)" << x << endl;};virtual void g(float x) {cout << "Base::g(float)" << x << endl ;};void h(float x) {cout << "Base::g(float)" << x << endl ; };
};class Derived : public Base{public : virtual void f(float x) {cout << "Derived::f(float)" << x << endl;};virtual void g(int x) {cout << "Derived::g(int)" << x << endl ;};void h(float x) {cout << "Derived::g(float)" << x << endl ; };
};int main(void ){Derived d;Base *pb = &d; // 父类指针指向子类对象Derived *pd = &d; // 子类指针指向子类对象 pb->f(3.14f); pd->f(3.14f); pd->Base::f(3.14f);pb->g(3.14f);pd->g(3.14f);pb->h(3.14f);pd->h(3.14f);return 0;}
结果:
发布评论