MST

星途 面试题库

面试题:C++中静态关联与动态关联在函数调用上的区别

请简述在C++中,静态关联和动态关联下函数调用的时机以及依据什么来确定调用的具体函数。分别举例说明静态关联和动态关联的函数调用场景。
41.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

静态关联

  • 调用时机:在编译期确定。
  • 确定调用函数依据:根据函数参数的静态类型(即声明时的类型)来确定调用哪个函数。编译器在编译时就知道要调用的具体函数版本。
  • 举例
class Animal {
public:
    void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() {
        std::cout << "Dog barks" << std::endl;
    }
};

int main() {
    Animal a;
    a.makeSound(); // 静态关联,编译期确定调用Animal::makeSound
    Dog d;
    d.makeSound(); // 静态关联,编译期确定调用Dog::makeSound
    Animal* ptr = &d;
    ptr->makeSound(); // 静态关联,因为ptr静态类型是Animal*,所以调用Animal::makeSound
    return 0;
}

动态关联

  • 调用时机:在运行期确定。
  • 确定调用函数依据:根据对象的实际类型(即运行时对象的真实类型)来确定调用哪个函数。这依赖于虚函数表(vtable)和虚函数指针(vptr)。当通过基类指针或引用调用虚函数时,运行时系统会根据对象的vptr找到对应的vtable,从而确定要调用的实际函数。
  • 举例
class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks" << std::endl;
    }
};

int main() {
    Animal* ptr = new Dog();
    ptr->makeSound(); // 动态关联,运行时根据ptr指向的实际对象类型Dog,调用Dog::makeSound
    delete ptr;
    return 0;
}