MST
星途 面试题库

面试题:C++中函数重载与虚函数在参数和调用机制上的区别

请阐述C++函数重载和虚函数在参数要求以及调用机制方面的主要区别。并举例说明在一个简单的类继承体系中,函数重载和虚函数分别是如何体现这些区别的。
24.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

参数要求区别

  • 函数重载:在同一作用域内,函数名相同,但参数列表(参数个数、类型或顺序)必须不同,返回值类型可以相同也可以不同。
  • 虚函数:在基类中声明为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类指针或对象调用。