首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C++面向对象编程】四大基本特性之三:多态

【C++面向对象编程】四大基本特性之三:多态

作者头像
byte轻骑兵
发布2026-01-20 17:07:45
发布2026-01-20 17:07:45
1250
举报

在C++面向对象编程中,多态(Polymorphism)是四大基本特性(封装、继承、多态、抽象)之一,它允许使用共同的接口来处理不同类型的对象,从而提高了代码的灵活性和可扩展性。多态使得同一个接口可以表现出不同的行为,这是通过继承和虚函数实现的。

一、多态的基本概念

1.1 什么是多态

多态按字面的意思就是“多种形态”。在面向对象编程中,多态指的是同一个接口(方法或函数调用)可以根据对象的实际类型表现出不同的行为。例如,动物发出声音的行为,猫和狗的实现方式不同,但可以通过同一个接口(如sound()方法)来调用。

1.2 多态的定义与分类

多态在 C++ 中主要分为两种类型:

①编译时多态(静态多态)

  • 通过函数重载(Function Overloading)和运算符重载(Operator Overloading)实现
  • 在编译阶段确定调用的函数版本

②运行时多态(动态多态)

  • 通过虚函数(Virtual Functions)和继承实现
  • 在运行时根据对象的实际类型确定调用的函数版本

1.3 多态的核心作用

  • 接口统一:通过基类定义统一的接口,派生类实现具体行为
  • 代码复用:减少重复代码,提高代码的可维护性
  • 可扩展性:新增派生类时无需修改现有代码,符合开闭原则
  • 动态绑定:运行时确定调用的函数版本,实现灵活的行为切换

二、编译时多态:函数重载与运算符重载

2.1 函数重载(Function Overloading)

函数重载允许在同一作用域内定义多个同名函数,但它们的参数列表(参数类型、数量或顺序)必须不同。编译器根据调用时的实参类型和数量选择匹配的函数。

示例:函数重载

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 函数重载示例
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

string add(const string& a, const string& b) {
    return a + b;
}

int main() {
    cout << add(1, 2) << endl;           // 调用add(int, int)
    cout << add(1.5, 2.5) << endl;       // 调用add(double, double)
    cout << add("Hello", " World") << endl; // 调用add(string, string)
    return 0;
}

函数重载的关键点:

  • 函数名必须相同
  • 参数列表必须不同(类型、数量或顺序)
  • 返回类型可以不同,但不能仅通过返回类型区分重载函数
  • 重载函数在编译阶段根据实参类型静态绑定

2.2 运算符重载(Operator Overloading)

运算符重载允许自定义类型使用 C++ 内置运算符(如+, -, *, /等),增强代码的可读性和直观性。

示例:复数类的运算符重载

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Complex {
private:
    double real;
    double imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载加法运算符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    // 重载输出流运算符
    friend ostream& operator<<(ostream& os, const Complex& c) {
        os << c.real << " + " << c.imag << "i";
        return os;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);
    Complex c3 = c1 + c2; // 调用operator+

    cout << "c1: " << c1 << endl;
    cout << "c2: " << c2 << endl;
    cout << "c1 + c2: " << c3 << endl;

    return 0;
}

运算符重载的关键点:

  • 通过定义特殊的成员函数或友元函数实现
  • 不能改变运算符的优先级、结合性和操作数数量
  • 部分运算符(如.::?:等)不能重载
  • 建议保持运算符原有语义,避免滥用

三、运行时多态:虚函数与动态绑定

3.1 虚函数(Virtual Functions)

虚函数是在基类中声明为virtual的函数,派生类可以通过相同的函数签名(函数名、参数列表、返回类型)重写(Override)该函数。通过基类指针或引用调用虚函数时,会在运行时根据对象的实际类型决定调用哪个版本的函数。

示例:动物类的虚函数

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak() { // 虚函数
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() override { // 重写基类虚函数
        cout << "Dog barks" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() override { // 重写基类虚函数
        cout << "Cat meows" << endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->speak(); // 输出: Dog barks
    animal2->speak(); // 输出: Cat meows

    delete animal1;
    delete animal2;
    return 0;
}

虚函数的关键点:

  • 在基类中使用virtual关键字声明
  • 派生类中使用override关键字(C++11 及以后)显式标记重写
  • 函数签名必须完全相同(返回类型可以是协变类型,见下文)
  • 通过基类指针或引用调用时实现动态绑定

3.2 动态绑定(Dynamic Binding)

动态绑定是运行时多态的核心机制,它允许在运行时根据对象的实际类型来决定调用哪个函数。动态绑定通过虚函数表(VTable)和虚表指针(VPTR)实现。

虚函数表与虚表指针:

  • 每个包含虚函数的类都有一个虚函数表(VTable),存储该类的虚函数地址
  • 每个对象都有一个虚表指针(VPTR),指向其所属类的虚函数表
  • 调用虚函数时,通过对象的 VPTR 找到对应的 VTable,再从 VTable 中找到函数地址并调用

示例:动态绑定机制

代码语言:javascript
复制
class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
};

class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
};

int main() {
    Base* ptr = new Derived();
    ptr->func1(); // 动态绑定:调用Derived::func1
    ptr->func2(); // 动态绑定:调用Base::func2
    delete ptr;
    return 0;
}

3.3 纯虚函数与抽象基类

纯虚函数是在基类中声明但不提供实现的虚函数,用= 0语法表示。包含纯虚函数的类称为抽象基类(Abstract Base Class),不能实例化。派生类必须实现所有纯虚函数才能成为具体类。

示例:抽象基类与纯虚函数

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Shape {
public:
    virtual double area() const = 0; // 纯虚函数
    virtual void draw() const = 0;   // 纯虚函数
};

class Circle : public Shape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}

    double area() const override { // 实现纯虚函数
        return 3.14 * radius * radius;
    }

    void draw() const override { // 实现纯虚函数
        cout << "Drawing a circle" << endl;
    }
};

int main() {
    // Shape s; // 错误:抽象基类不能实例化
    Shape* shape = new Circle(5);
    cout << "Area: " << shape->area() << endl;
    shape->draw();
    delete shape;
    return 0;
}

抽象基类的关键点:

  • 定义接口规范,强制派生类实现特定功能
  • 用作基类,通过指针或引用实现多态
  • 可包含普通成员函数和数据成员
  • 抽象基类的派生类若未实现所有纯虚函数,仍为抽象基类

四、多态的高级特性

4.1 协变返回类型(Covariant Return Types)

C++ 允许派生类虚函数的返回类型是基类虚函数返回类型的指针或引用,这种特性称为协变返回类型。

示例:协变返回类型

代码语言:javascript
复制
#include <iostream>
#include <typeinfo>
using namespace std;

// 基类:添加虚析构函数
class Base {
public:
    virtual Base* clone() {
        cout << "Base::clone" << endl;
        return new Base();
    }
    virtual ~Base() {} // 虚析构函数
};

// 派生类:添加析构函数(若有资源需释放)
class Derived : public Base {
public:
    Derived* clone() override { // 协变返回类型
        cout << "Derived::clone" << endl;
        return new Derived();
    }
    ~Derived() override { // 可选:若有资源需释放,重写析构函数
        cout << "Derived::~Derived" << endl;
    }
};

int main() {
    Base* basePtr = new Derived();

    // 调用 clone() 返回 Base*(运行时实际是 Derived*)
    Base* clonedBase = basePtr->clone();

    // 使用 dynamic_cast 安全转换为 Derived*
    Derived* derivedPtr = dynamic_cast<Derived*>(clonedBase);
    if (derivedPtr) {
        cout << "Successfully converted to Derived*" << endl;
    } else {
        cerr << "Error: cloned object is not of type Derived" << endl;
    }

    // 释放内存(虚析构函数确保正确调用派生类析构)
    delete basePtr;
    delete clonedBase; // 或 delete derivedPtr(若转换成功)

    return 0;
}

4.2 虚析构函数(Virtual Destructors)

当通过基类指针删除派生类对象时,如果基类析构函数不是虚函数,只会调用基类的析构函数,导致派生类部分资源无法释放,造成内存泄漏。因此,基类的析构函数通常应声明为虚函数。

示例:虚析构函数的必要性

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Base {
public:
    virtual ~Base() { // 虚析构函数
        cout << "Base destructor" << endl;
    }
};

class Derived : public Base {
private:
    int* data;

public:
    Derived() {
        data = new int[100];
        cout << "Derived constructor" << endl;
    }

    ~Derived() override {
        delete[] data;
        cout << "Derived destructor" << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    delete ptr; // 输出:Derived destructor → Base destructor
    return 0;
}

4.3 纯虚析构函数(Pure Virtual Destructors)

纯虚析构函数允许将类定义为抽象基类,同时必须为其提供实现(因为所有析构函数都会在对象销毁时被调用)。

示例:纯虚析构函数

代码语言:javascript
复制
class Base {
public:
    virtual ~Base() = 0; // 纯虚析构函数
};

// 必须提供纯虚析构函数的实现
Base::~Base() {
    cout << "Base pure virtual destructor" << endl;
}

class Derived : public Base {
public:
    ~Derived() override {
        cout << "Derived destructor" << endl;
    }
};

4.4 虚函数与默认参数

虚函数的默认参数值是在编译时确定的,而不是运行时。因此,通过基类指针或引用调用虚函数时,默认参数值由指针或引用的静态类型决定,而非对象的实际类型。

示例:虚函数与默认参数

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Base {
public:
    virtual void print(int x = 10) {
        cout << "Base::print x = " << x << endl;
    }
};

class Derived : public Base {
public:
    void print(int x = 20) override {
        cout << "Derived::print x = " << x << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    ptr->print(); // 输出:Derived::print x = 10(默认参数来自Base)
    delete ptr;
    return 0;
}

五、多态的应用场景

5.1 策略模式(Strategy Pattern)

策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

示例:策略模式实现

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 策略接口
class SortStrategy {
public:
    virtual void sort() = 0;
    virtual ~SortStrategy() {}
};

// 具体策略:冒泡排序
class BubbleSort : public SortStrategy {
public:
    void sort() override {
        cout << "Sorting using Bubble Sort" << endl;
    }
};

// 具体策略:快速排序
class QuickSort : public SortStrategy {
public:
    void sort() override {
        cout << "Sorting using Quick Sort" << endl;
    }
};

// 上下文类
class Sorter {
private:
    SortStrategy* strategy;

public:
    Sorter(SortStrategy* s) : strategy(s) {}
    ~Sorter() { delete strategy; }

    void setStrategy(SortStrategy* s) {
        delete strategy;
        strategy = s;
    }

    void performSort() {
        strategy->sort();
    }
};

int main() {
    Sorter sorter(new BubbleSort());
    sorter.performSort(); // 输出:Sorting using Bubble Sort

    sorter.setStrategy(new QuickSort());
    sorter.performSort(); // 输出:Sorting using Quick Sort

    return 0;
}

5.2 工厂模式(Factory Pattern)

工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离。通过工厂模式,可以根据不同的条件创建不同类型的对象。

示例:工厂模式实现

代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

// 产品基类
class Shape {
public:
    virtual void draw() = 0;
    virtual ~Shape() {}
};

// 具体产品:圆形
class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing a circle" << endl;
    }
};

// 具体产品:矩形
class Rectangle : public Shape {
public:
    void draw() override {
        cout << "Drawing a rectangle" << endl;
    }
};

// 工厂类
class ShapeFactory {
public:
    static Shape* createShape(const string& type) {
        if (type == "circle") {
            return new Circle();
        } else if (type == "rectangle") {
            return new Rectangle();
        }
        return nullptr;
    }
};

int main() {
    Shape* circle = ShapeFactory::createShape("circle");
    circle->draw(); // 输出:Drawing a circle

    Shape* rectangle = ShapeFactory::createShape("rectangle");
    rectangle->draw(); // 输出:Drawing a rectangle

    delete circle;
    delete rectangle;
    return 0;
}

5.3 容器中的多态对象

通过基类指针或智能指针,可以在容器中存储不同类型的派生类对象,实现多态容器。

示例:多态容器

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <memory>
using namespace std;

class Animal {
public:
    virtual void speak() {
        cout << "Animal speaks" << endl;
    }
    virtual ~Animal() {}
};

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

class Cat : public Animal {
public:
    void speak() override {
        cout << "Cat meows" << endl;
    }
};

int main() {
    // 使用智能指针的多态容器
    vector<unique_ptr<Animal>> animals;
    animals.push_back(make_unique<Dog>());
    animals.push_back(make_unique<Cat>());

    // 遍历容器,调用多态方法
    for (const auto& animal : animals) {
        animal->speak();
    }

    return 0;
}

六、多态与继承、封装的关系

6.1 多态与继承

继承是多态的基础。通过继承,子类可以重写父类的虚函数,从而使得在运行时根据对象类型调用正确的函数。没有继承,多态就无法实现。

6.2 多态与封装

封装是指将数据和操作数据的方法绑定在一起,并隐藏对象的内部实现细节,仅暴露必要的接口。多态与封装相结合,可以使得程序更加模块化和易于维护。通过封装,可以隐藏对象的内部状态和行为,而通过多态,可以使得程序能够以统一的方式处理不同类型的对象。

6.3 示例代码

以下是一个结合了继承、封装和多态的示例,展示了它们之间的关系:

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <vector>

using namespace std;

// 基类 Animal(封装:隐藏内部实现细节)
class Animal {
private:
    string name;

public:
    Animal(const string& n) : name(n) {}

    string getName() const {
        return name;
    }

    virtual void sound() const = 0; // 纯虚函数,多态的基础
    virtual ~Animal() {}            // 虚析构函数
};

// 派生类 Dog(继承和多态)
class Dog : public Animal {
public:
    Dog(const string& n) : Animal(n) {}

    void sound() const override {
        cout << getName() << " says: Woof! Woof!" << endl;
    }
};

// 派生类 Cat(继承和多态)
class Cat : public Animal {
public:
    Cat(const string& n) : Animal(n) {}

    void sound() const override {
        cout << getName() << " says: Meow! Meow!" << endl;
    }
};

// 派生类 Bird(继承和多态)
class Bird : public Animal {
public:
    Bird(const string& n) : Animal(n) {}

    void sound() const override {
        cout << getName() << " says: Chirp! Chirp!" << endl;
    }
};

// 测试多态
void makeAnimalSound(const Animal* animal) {
    animal->sound(); // 动态绑定:根据对象的实际类型调用相应的sound方法
}

int main() {
    vector<Animal*> animals;
    animals.push_back(new Dog("Buddy"));
    animals.push_back(new Cat("Whiskers"));
    animals.push_back(new Bird("Tweety"));

    for (Animal* animal : animals) {
        makeAnimalSound(animal); // 动态绑定:根据对象的实际类型调用相应的sound方法
    }

    // 释放内存
    for (Animal* animal : animals) {
        delete animal;
    }

    return 0;
}

七、多态的性能与注意事项

7.1 性能开销

运行时多态(虚函数)会带来一定的性能开销:

  • 虚函数调用比普通函数调用慢,因为需要通过虚表指针间接调用
  • 每个包含虚函数的对象都会增加一个虚表指针的内存开销
  • 虚函数表会增加类的静态内存占用

7.2 注意事项

  1. 虚函数的滥用:避免在不需要多态的地方使用虚函数,以免增加性能开销
  2. 构造函数与虚函数:构造函数不能是虚函数,因为在构造时对象类型尚未完全确定
  3. 析构函数必须为虚函数:当通过基类指针删除派生类对象时,必须确保基类析构函数是虚函数
  4. 纯虚函数的实现:纯虚函数必须在派生类中实现,否则派生类仍为抽象基类
  5. 默认参数与虚函数:虚函数的默认参数值由静态类型决定,可能导致意外行为

八、完整示例:多态的综合应用

下面是一个综合应用多态的示例,实现一个简单的图形绘制系统:

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <memory> // 包含 unique_ptr
#include <cmath>
using namespace std;

// ====================== 抽象基类:图形 ======================
class Shape {
public:
    virtual string getName() const = 0;
    virtual double getArea() const = 0;
    virtual void draw() const = 0;
    virtual ~Shape() {} // 虚析构函数确保多态释放
};

// ====================== 二维图形基类 ======================
class TwoDShape : public Shape {
public:
    double getArea() const override = 0;
};

// ====================== 三维图形基类 ======================
class ThreeDShape : public Shape {
public:
    virtual double getVolume() const = 0;
    double getArea() const override { return getSurfaceArea(); }
    virtual double getSurfaceArea() const = 0;
};

// ====================== 派生类:圆形 ======================
class Circle : public TwoDShape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}

    string getName() const override { return "Circle"; }
    double getArea() const override { return M_PI * radius * radius; }
    void draw() const override {
        cout << "Drawing a circle with radius " << radius << endl;
    }
};

// ====================== 派生类:矩形 ======================
class Rectangle : public TwoDShape {
private:
    double width;
    double height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    string getName() const override { return "Rectangle"; }
    double getArea() const override { return width * height; }
    void draw() const override {
        cout << "Drawing a rectangle with width " << width 
             << " and height " << height << endl;
    }
};

// ====================== 派生类:球体 ======================
class Sphere : public ThreeDShape {
private:
    double radius;

public:
    Sphere(double r) : radius(r) {}

    string getName() const override { return "Sphere"; }
    double getVolume() const override { return (4.0/3.0) * M_PI * pow(radius, 3); }
    double getSurfaceArea() const override { return 4 * M_PI * radius * radius; }
    void draw() const override {
        cout << "Drawing a sphere with radius " << radius << endl;
    }
};

// ====================== 派生类:立方体 ======================
class Cube : public ThreeDShape {
private:
    double side;

public:
    Cube(double s) : side(s) {}

    string getName() const override { return "Cube"; }
    double getVolume() const override { return pow(side, 3); }
    double getSurfaceArea() const override { return 6 * side * side; }
    void draw() const override {
        cout << "Drawing a cube with side length " << side << endl;
    }
};

// ====================== 图形管理器 ======================
class ShapeManager {
private:
    vector<unique_ptr<Shape>> shapes;

public:
    void addShape(unique_ptr<Shape> shape) {
        shapes.push_back(move(shape)); // 转移所有权
    }

    void drawAll() const {
        for (const auto& shape : shapes) {
            shape->draw();
            cout << "Name: " << shape->getName() 
                 << ", Area: " << shape->getArea();
            
            // 动态类型转换判断是否为三维图形
            if (auto* threeDShape = dynamic_cast<const ThreeDShape*>(shape.get())) {
                cout << ", Volume: " << threeDShape->getVolume();
            }
            cout << endl << "------------------------" << endl;
        }
    }
};

// ====================== 主函数 ======================
int main() {
    ShapeManager manager;

    // C++11 兼容写法:手动用 new 创建对象,传递给 unique_ptr
    manager.addShape(unique_ptr<Shape>(new Circle(5)));
    manager.addShape(unique_ptr<Shape>(new Rectangle(4, 6)));
    manager.addShape(unique_ptr<Shape>(new Sphere(3)));
    manager.addShape(unique_ptr<Shape>(new Cube(2)));

    // 绘制所有图形并显示信息
    manager.drawAll();

    return 0;
}

九、多态的最佳实践

9.1 合理使用虚函数

  • 定义虚函数:如果希望派生类能够重写基类的方法,应将其定义为虚函数。
  • 避免滥用虚函数:虚函数虽然强大,但也会带来一定的运行时开销,应合理使用。

9.2 使用overridefinal关键字

  • override关键字:用于检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。有助于避免由于疏忽而导致的函数名拼写错误等问题。
  • final关键字:用于修饰虚函数,表示该虚函数不能再被重写;也可以用于修饰类,表示该类不能被继承。

9.3 避免虚函数调用开销

  • 性能考虑:虚函数的调用涉及虚函数表的查找,会带来一定的运行时开销。在性能敏感的场景中,应谨慎使用虚函数。
  • 非虚函数优化:对于不需要多态的成员函数,应声明为非虚函数,以提高性能。

9.4 合理设计类层次结构

  • 明确继承关系:确保派生类与基类之间存在合理的“is-a”关系。
  • 避免过度继承:继承层次不宜过深,以免增加代码复杂性和维护难度。
  • 保持一致性:在整个应用程序中保持继承层次的一致性和规范性。

十、总结

多态是 C++ 面向对象编程的核心特性之一,它通过统一的接口实现不同的行为,使代码更加灵活、可扩展和可维护。编译时多态通过函数重载和运算符重载实现,运行时多态通过虚函数和动态绑定实现。在设计复杂系统时,合理应用多态可以显著提高代码的质量和可维护性。

关键知识点回顾:

  • 编译时多态与运行时多态的区别
  • 虚函数的声明与重写
  • 纯虚函数与抽象基类的应用
  • 虚析构函数的必要性
  • 多态在设计模式中的应用
  • 多态的性能开销与注意事项

通过深入理解和掌握多态机制,将能够设计出更加优雅、灵活和可扩展的 C++ 程序。


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、多态的基本概念
    • 1.1 什么是多态
    • 1.2 多态的定义与分类
    • 1.3 多态的核心作用
  • 二、编译时多态:函数重载与运算符重载
    • 2.1 函数重载(Function Overloading)
    • 2.2 运算符重载(Operator Overloading)
  • 三、运行时多态:虚函数与动态绑定
    • 3.1 虚函数(Virtual Functions)
    • 3.2 动态绑定(Dynamic Binding)
    • 3.3 纯虚函数与抽象基类
  • 四、多态的高级特性
    • 4.1 协变返回类型(Covariant Return Types)
    • 4.2 虚析构函数(Virtual Destructors)
    • 4.3 纯虚析构函数(Pure Virtual Destructors)
    • 4.4 虚函数与默认参数
  • 五、多态的应用场景
    • 5.1 策略模式(Strategy Pattern)
    • 5.2 工厂模式(Factory Pattern)
    • 5.3 容器中的多态对象
  • 六、多态与继承、封装的关系
    • 6.1 多态与继承
    • 6.2 多态与封装
    • 6.3 示例代码
  • 七、多态的性能与注意事项
    • 7.1 性能开销
    • 7.2 注意事项
  • 八、完整示例:多态的综合应用
  • 九、多态的最佳实践
    • 9.1 合理使用虚函数
    • 9.2 使用override和final关键字
    • 9.3 避免虚函数调用开销
    • 9.4 合理设计类层次结构
  • 十、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档