[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)使用父类指针调用函数,结果要看该函数是否是虚函数,若为虚函数则使用子类版本。
浙公网安备 33010602011771号