首页 > 后端开发 > C++ > 正文

C++中如何实现多态特性_多态实现原理与代码示例

尼克
发布: 2025-08-16 18:43:01
原创
200人浏览过

c++++中多态的核心在于通过虚函数实现“一个接口,多种方法”。1. 使用virtual关键字在基类中声明虚函数;2. 派生类重写虚函数并使用override提高可读性;3. 通过基类指针或引用调用虚函数,实际执行派生类的实现。若不使用虚函数,则调用始终绑定到基类函数。虚函数表(vtable)在编译时生成,存储虚函数地址,对象通过虚函数指针(vptr)访问对应vtable以实现运行时动态绑定。纯虚函数使类成为抽象类,必须被继承并重写才能实例化派生类。多重继承下,派生类可能拥有多个vptr以支持不同基类的虚函数调用。

C++中如何实现多态特性_多态实现原理与代码示例

C++中多态的核心在于允许你使用指向基类的指针或引用来调用派生类中的函数,从而实现“一个接口,多种方法”。 这背后的机制涉及虚函数表(vtable)和虚函数指针(vptr),使得在运行时能够确定实际调用的函数。

C++中如何实现多态特性_多态实现原理与代码示例

解决方案

多态的实现主要依赖于虚函数。 当一个类中声明了虚函数,编译器会为该类创建一个虚函数表(vtable),其中存储了该类及其父类的虚函数地址。 类的每个对象都会包含一个指向该vtable的虚函数指针(vptr)。

C++中如何实现多态特性_多态实现原理与代码示例
  1. 虚函数声明: 在基类中使用

    virtual
    登录后复制
    关键字声明虚函数。

    立即学习C++免费学习笔记(深入)”;

    class Base {
    public:
        virtual void display() {
            std::cout << "Base class display" << std::endl;
        }
    };
    登录后复制
  2. 派生类重写: 在派生类中重写(override)基类的虚函数。 注意override关键字可以提高代码可读性,避免错误。

    C++中如何实现多态特性_多态实现原理与代码示例
    class Derived : public Base {
    public:
        void display() override {
            std::cout << "Derived class display" << std::endl;
        }
    };
    登录后复制
  3. 通过指针或引用调用: 通过基类指针或引用调用虚函数。

    Base* basePtr;
    Derived derivedObj;
    basePtr = &derivedObj;
    basePtr->display(); // 输出 "Derived class display"
    登录后复制

在这个例子中,

basePtr
登录后复制
指向的是
Derived
登录后复制
类的对象,尽管
basePtr
登录后复制
Base
登录后复制
类型的指针,但由于
display
登录后复制
函数是虚函数,所以实际调用的是
Derived
登录后复制
类中的
display
登录后复制
函数。 这就是多态的体现。

那么,没有虚函数会怎样? 如果

display
登录后复制
函数不是虚函数,那么
basePtr->display()
登录后复制
将始终调用
Base
登录后复制
类中的
display
登录后复制
函数,即使
basePtr
登录后复制
指向的是
Derived
登录后复制
类的对象。

ViiTor实时翻译
ViiTor实时翻译

AI实时多语言翻译专家!强大的语音识别、AR翻译功能。

ViiTor实时翻译 116
查看详情 ViiTor实时翻译

什么是虚函数表(vtable)?

虚函数表(vtable)是一个存储类虚函数地址的查找表。 每个包含虚函数的类都有一个 vtable。 vtable 是编译器在编译时生成的,通常是静态的。 类的每个对象(包含虚函数)都会有一个指向其 vtable 的指针(vptr)。 这个指针通常位于对象的内存布局的起始位置。

vtable 使得在运行时能够动态地确定应该调用哪个函数。 当通过基类指针或引用调用虚函数时,程序会通过 vptr 找到 vtable,然后在 vtable 中查找正确的函数地址并调用它。

纯虚函数与抽象类

纯虚函数是在基类中声明但没有定义的虚函数。 包含纯虚函数的类被称为抽象类。 抽象类不能被实例化,只能被继承。 派生类必须重写基类中的所有纯虚函数才能被实例化。

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

class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    double area() override { return 3.14159 * radius * radius; }
private:
    double radius;
};
登录后复制

在这个例子中,

Shape
登录后复制
是一个抽象类,因为它包含一个纯虚函数
area()
登录后复制
Circle
登录后复制
类继承了
Shape
登录后复制
类并重写了
area()
登录后复制
函数,因此
Circle
登录后复制
类可以被实例化。 如果
Circle
登录后复制
类没有重写
area()
登录后复制
函数,那么
Circle
登录后复制
类也将是一个抽象类。

多重继承与多态

多重继承是指一个类继承自多个基类。 在多重继承的情况下,派生类可能会有多个 vptr,每个 vptr 指向一个基类的 vtable。 这会增加多态实现的复杂性,需要仔细设计类的继承关系和虚函数。

例如:

class Base1 {
public:
    virtual void display() { std::cout << "Base1" << std::endl; }
};

class Base2 {
public:
    virtual void show() { std::cout << "Base2" << std::endl; }
};

class Derived : public Base1, public Base2 {
public:
    void display() override { std::cout << "Derived (Base1)" << std::endl; }
    void show() override { std::cout << "Derived (Base2)" << std::endl; }
};

int main() {
    Derived d;
    Base1* b1 = &d;
    Base2* b2 = &d;

    b1->display(); // 输出 "Derived (Base1)"
    b2->show();    // 输出 "Derived (Base2)"

    return 0;
}
登录后复制

在这个例子中,

Derived
登录后复制
类继承自
Base1
登录后复制
Base2
登录后复制
Derived
登录后复制
类重写了
Base1
登录后复制
display
登录后复制
函数和
Base2
登录后复制
show
登录后复制
函数。 通过
Base1
登录后复制
Base2
登录后复制
的指针调用虚函数时,会分别调用
Derived
登录后复制
类中对应的函数。 注意,这里
Derived
登录后复制
类对象实际上有两个 vptr,分别对应
Base1
登录后复制
Base2
登录后复制

以上就是C++中如何实现多态特性_多态实现原理与代码示例的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号