MST

星途 面试题库

面试题:C++ 中静态联编和动态联编的区别

请详细阐述C++中静态联编和动态联编的概念、实现方式及应用场景,并举例说明两者的差异。
25.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

静态联编

  1. 概念:静态联编是在编译阶段就确定了函数调用与函数实现之间的关系,也称为早期绑定。编译器在编译时,根据对象的类型来确定调用哪个函数。
  2. 实现方式:通过函数重载和运算符重载来实现。在编译期间,编译器根据函数参数的类型和个数来选择合适的函数版本。例如对于函数 void func(int);void func(double);,编译器依据传入参数类型决定调用哪个。
  3. 应用场景:适用于在编译期就能确定要调用哪个函数的场景,比如一些基础的工具函数,像数学计算函数等,编译时明确函数版本可提高执行效率。

动态联编

  1. 概念:动态联编是在运行阶段才确定函数调用与函数实现之间的关系,也叫晚期绑定。程序在运行时根据对象的实际类型来决定调用哪个虚函数。
  2. 实现方式:通过虚函数和指针或引用实现。当使用基类指针或引用调用虚函数时,实际调用的函数是指针或引用所指向对象的实际类型的虚函数版本。这依赖于虚函数表(vtable)和虚指针(vptr)机制,每个包含虚函数的类都有一个虚函数表,对象内部有一个虚指针指向该虚函数表,运行时根据虚指针找到对应的虚函数。
  3. 应用场景:常用于实现多态性,在面向对象设计中,当需要根据对象的实际类型执行不同操作时使用。比如在图形绘制系统中,基类 Shape 有虚函数 drawCircleRectangle 等子类继承 Shape 并重写 draw 函数,通过基类指针或引用调用 draw 函数时,运行时根据实际对象类型决定绘制圆形还是矩形。

两者差异举例

#include <iostream>
class Base {
public:
    // 虚函数,用于动态联编
    virtual void print() {
        std::cout << "This is Base class" << std::endl;
    }
    // 普通函数,用于静态联编
    void show() {
        std::cout << "Base show" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        std::cout << "This is Derived class" << std::endl;
    }
    void show() {
        std::cout << "Derived show" << std::endl;
    }
};

int main() {
    Base baseObj;
    Derived derivedObj;

    // 静态联编
    baseObj.show();
    derivedObj.show();

    Base* basePtr = &baseObj;
    // 动态联编
    basePtr->print();

    basePtr = &derivedObj;
    // 动态联编,根据实际对象类型调用 Derived 的 print 函数
    basePtr->print();

    return 0;
}

在上述代码中,show 函数通过对象调用,属于静态联编,编译时就确定调用哪个函数。而 print 函数通过基类指针调用,属于动态联编,运行时根据指针实际指向的对象类型决定调用哪个 print 函数版本。