MST

星途 面试题库

面试题:C++ 中 static 函数与普通函数在多态性表现上的差异

在 C++ 多态性的情境下,分析 static 函数和普通函数在虚函数机制、动态绑定等方面的不同行为,举例说明。
26.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. static 函数与虚函数机制、动态绑定的关系

  • 虚函数机制
    • static 函数static函数不属于任何对象实例,它不参与虚函数机制。虚函数是基于对象的动态类型来实现多态行为,而static函数没有“对象的动态类型”这个概念,因为它与对象实例无关。
    • 普通函数:普通成员函数可以声明为虚函数。一旦声明为虚函数,在派生类中可以重写(override),从而实现多态行为。
  • 动态绑定
    • static 函数:不支持动态绑定。static函数的调用是在编译期确定的,根据调用函数的对象指针或引用的静态类型来确定调用哪个static函数,与对象的实际类型无关。
    • 普通函数:普通虚函数支持动态绑定。在通过基类指针或引用调用虚函数时,会在运行期根据对象的实际类型来决定调用哪个函数版本,即实现动态绑定。

2. 示例代码

#include <iostream>

class Base {
public:
    static void staticFunction() {
        std::cout << "Base::staticFunction" << std::endl;
    }

    virtual void virtualFunction() {
        std::cout << "Base::virtualFunction" << std::endl;
    }
};

class Derived : public Base {
public:
    static void staticFunction() {
        std::cout << "Derived::staticFunction" << std::endl;
    }

    void virtualFunction() override {
        std::cout << "Derived::virtualFunction" << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    // 调用 static 函数,根据指针的静态类型(Base*)确定调用 Base::staticFunction
    basePtr->staticFunction();
    // 调用虚函数,根据对象的实际类型(Derived)确定调用 Derived::virtualFunction
    basePtr->virtualFunction();

    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    if (derivedPtr) {
        // 调用 static 函数,根据指针的静态类型(Derived*)确定调用 Derived::staticFunction
        derivedPtr->staticFunction();
    }

    delete basePtr;
    return 0;
}

在上述代码中:

  • 对于staticFunction,无论basePtr指向Base对象还是Derived对象,通过basePtr调用staticFunction都是调用Base类的staticFunction,因为static函数调用是基于指针的静态类型。
  • 对于virtualFunction,由于它是虚函数,通过basePtr调用时,会根据basePtr所指向对象的实际类型(这里是Derived),调用Derived类的virtualFunction,体现了动态绑定。