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

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

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

虚函数声明: 在基类中使用
virtual
关键字声明虚函数。
立即学习“C++免费学习笔记(深入)”;
class Base {public: virtual void display() { std::cout << "Base class display" << std::endl; }};
派生类重写: 在派生类中重写(override)基类的虚函数。 注意override关键字可以提高代码可读性,避免错误。

class Derived : public Base {public: void display() override { std::cout << "Derived class display" << std::endl; }};
通过指针或引用调用: 通过基类指针或引用调用虚函数。
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
类的对象。
什么是虚函数表(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)" <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++中如何实现多态特性_多态实现原理与代码示例的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1471455.html
微信扫一扫
支付宝扫一扫