MST
星途 面试题库

面试题:C++类的继承与多态性实现原理

在C++中,详细阐述类的继承和多态性是如何实现的。请举例说明虚函数、纯虚函数和虚析构函数在实现多态性方面的作用,以及运行时多态和编译时多态的区别。
41.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

类的继承实现

在C++中,通过关键字publicprotectedprivate来定义继承方式,子类继承父类语法如下:

class Parent {
    // 成员
};
class Child : public Parent {
    // 新增成员
};

public继承使得父类的publicprotected成员在子类中保持原访问属性;protected继承会让父类的publicprotected成员在子类中变为protectedprivate继承使父类的publicprotected成员在子类中变为private

多态性实现

  1. 编译时多态:通过函数重载和模板实现。函数重载是指在同一作用域内,多个函数可以具有相同名称但参数列表不同。模板则是一种通用的编程机制,允许编写参数化类型的代码。
    // 函数重载示例
    void func(int a) { /* 实现 */ }
    void func(double a) { /* 实现 */ }
    
    // 模板示例
    template <typename T>
    T add(T a, T b) { return a + b; }
    
  2. 运行时多态:依赖虚函数和指针或引用实现。当通过基类指针或引用调用虚函数时,实际调用的函数版本取决于指针或引用所指向对象的实际类型。

虚函数作用

虚函数允许在子类中被重写,以实现不同的行为。基类中声明虚函数使用virtual关键字。

class Shape {
public:
    virtual double area() { return 0.0; }
};
class Circle : public Shape {
public:
    double area() override { /* 圆面积计算 */ }
};
class Rectangle : public Shape {
public:
    double area() override { /* 矩形面积计算 */ }
};

通过基类指针或引用调用area函数时,会根据实际对象类型调用相应子类的area函数,实现运行时多态。

纯虚函数作用

纯虚函数没有函数体,在基类中定义为virtual 返回类型 函数名(参数列表)=0;。包含纯虚函数的类是抽象类,不能实例化对象。

class Shape {
public:
    virtual double area() = 0;
};
class Circle : public Shape {
public:
    double area() override { /* 圆面积计算 */ }
};

纯虚函数强制子类必须重写该函数,为多态提供了统一的接口规范。

虚析构函数作用

虚析构函数确保在通过基类指针删除对象时,能正确调用子类的析构函数,防止内存泄漏。

class Base {
public:
    virtual ~Base() {}
};
class Derived : public Base {
public:
    ~Derived() {}
};

如果Base的析构函数不是虚函数,当delete一个指向Derived对象的Base指针时,只会调用Base的析构函数,而不会调用Derived的析构函数。

运行时多态和编译时多态区别

  • 运行时多态:在运行期间根据对象实际类型决定调用哪个函数版本,依赖虚函数和指针或引用,开销相对较大,因为需要通过虚函数表查找函数地址。
  • 编译时多态:在编译期间根据函数参数类型和模板参数决定调用哪个函数版本,通过函数重载和模板实现,效率高,因为编译器在编译时就确定了调用的函数。