面试题答案
一键面试参数要求区别
- 函数重载:在同一作用域内,函数名相同,但参数列表(参数个数、类型或顺序)必须不同,返回值类型可以相同也可以不同。
- 虚函数:在基类中声明为
virtual
,在派生类中重写(函数名、参数列表、返回值类型都必须与基类中的虚函数相同,协变返回类型除外)。
调用机制区别
- 函数重载:根据调用函数时传递的实际参数,在编译期确定调用哪个函数,即静态绑定。
- 虚函数:在运行时,根据对象的实际类型(动态类型)来确定调用哪个函数,即动态绑定。
简单类继承体系示例
#include <iostream>
class Base {
public:
// 虚函数
virtual void func(int num) {
std::cout << "Base::func(int) " << num << std::endl;
}
// 函数重载
void func(double num) {
std::cout << "Base::func(double) " << num << std::endl;
}
};
class Derived : public Base {
public:
// 重写虚函数
void func(int num) override {
std::cout << "Derived::func(int) " << num << std::endl;
}
// 新的函数重载
void func(float num) {
std::cout << "Derived::func(float) " << num << std::endl;
}
};
int main() {
Base* basePtr1 = new Base();
Base* basePtr2 = new Derived();
basePtr1->func(10); // 调用 Base::func(int),静态绑定
basePtr2->func(10); // 调用 Derived::func(int),动态绑定
basePtr1->func(10.5); // 调用 Base::func(double),静态绑定
// basePtr2->func(10.5f); // 编译错误,Base类指针不能调用Derived类特有的重载函数
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr2);
if (derivedPtr) {
derivedPtr->func(10.5f); // 调用 Derived::func(float),静态绑定
}
delete basePtr1;
delete basePtr2;
return 0;
}
在上述代码中,Base
类中有func
函数的重载版本,根据参数类型在编译期确定调用哪个函数。而func(int)
是虚函数,在运行时根据对象实际类型确定调用Base::func(int)
还是Derived::func(int)
。Derived
类中新增了func(float)
作为新的重载函数,只能通过Derived
类指针或对象调用。