[C++] 函数覆盖、隐藏、重载

参考博客: https://blog.csdn.net/lu597203933/article/details/8992687

1. 函数重载

同一个类中,函数名相同,但是参数列表或者参数类型不同。

也就是说有多个同名的函数,在调用时,会根据函数名、参数名、参数类型来决定调用哪一个。

2. 函数覆盖

1)非虚函数覆盖

发生在类继承时,当存在同名基类函数不为虚函数且函数名称、参数列表完全相同时。

由于函数是非虚的,因此调用函数的版本是根据类型决定。也就是说当使用父类指针调用子类的函数时,调用到的函数是父类的函数。

例1:父类指针访问子类func

Child child;
Parent* parent = &child;
parent->func(); // 通过父类指针调用父类的func

例2:通过作用域访问父类func

Child child;
child.Parent::func(); // 通过作用域调用父类的fun

2)虚函数覆盖

发生在类继承时,当存在同名基类函数为虚函数且函数名称、参数列表完全相同时。(函数修饰符也需要相同,例如const)

由于虚函数是在运行时被获得并记录在类的虚函数表中,因此当子类继承时,虚函数表中的函数指针将指向子类的函数。

也就是说,覆盖之后,从子类实例调用到的函数将会是覆盖后的函数。而当使用父类指针调用子类的函数时,调用到的函数 依然 是覆盖后的函数。

例1:父类指针访问子类func

Child child;
Parent* parent = &child;
parent->func(); // 通过父类指针调用子类的fun

例2:通过作用域访问父类func

Child child;
child.Parent::func(); // 通过作用域调用父类的fun

3)补充

使用父类引用调用子类的效果和使用指针相似。

若将子类赋值给父类,会调用父类的拷贝构造函数,因此不会影响父类的虚函数表,这样做调用到的依然是父类的函数。

3. 函数隐藏

1)隐藏条件

发生在类继承时,当存在同名基类函数不为虚函数且函数名相同时。(注意不需要参数列表也相同

也就是说,假设基类中同名函数func有三个重载版本,而基类只覆盖了其中一个版本,则其他版本会被隐藏。表现为不能直接从子类作用域调用。

2)调用被隐藏的函数

可以通过作用域运算符调用被子类覆盖或被隐藏的函数。

例如 child 继承自 parent类,隐藏(或覆盖)了函数func。可以这样调用父类的版本:

child.parent::func();

3)为何设计函数隐藏机制

由于C++支持继承多个类,可能导致不知道继承哪一个基类的函数,干脆就隐藏掉。

4. 补充

1)可以在类中定义同名函数的多个版本,且全是虚函数。

2)可以在类中定义同名函数的多个版本,其中一个版本是虚函数,其余不是。

3)函数隐藏会发生在同名函数的所有没有被覆盖的版本上,不论是否是虚函数。

4)使用父类指针调用函数,结果要看该函数是否是虚函数,若为虚函数则使用子类版本。

posted @ 2022-02-20 17:31  Cheung-10  阅读(6)  评论(0)    收藏  举报