多态按字面的意思就是多种形态。
当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。
在 C++ 中,多态(Polymorphism)是面向对象编程的重要特性之一。
C++ 多态允许使用基类指针或引用来调用子类的重写方法,从而使得同一接口可以表现不同的行为。
多态使得代码更加灵活和通用,程序可以通过基类指针或引用来操作不同类型的对象,而不需要显式区分对象类型。这样可以使代码更具扩展性,在增加新的形状类时不需要修改主程序。
以下是多态的几个关键点:
虚函数(Virtual Functions):
- 在基类中声明一个函数为虚函数,使用关键字
virtual
。 - 派生类可以重写(override)这个虚函数。
- 调用虚函数时,会根据对象的实际类型来决定调用哪个版本的函数。
动态绑定(Dynamic Binding):
- 也称为晚期绑定(Late Binding),在运行时确定函数调用的具体实现。
- 需要使用指向基类的指针或引用来调用虚函数,编译器在运行时根据对象的实际类型来决定调用哪个函数。
纯虚函数(Pure Virtual Functions):
- 一个包含纯虚函数的类被称为抽象类(Abstract Class),它不能被直接实例化。
- 纯虚函数没有函数体,声明时使用
= 0
。 - 它强制派生类提供具体的实现。
多态的实现机制:
- 虚函数表(V-Table):C++运行时使用虚函数表来实现多态。每个包含虚函数的类都有一个虚函数表,表中存储了指向类中所有虚函数的指针。
- 虚函数指针(V-Ptr):对象中包含一个指向该类虚函数表的指针。
使用多态的优势:
- 代码复用:通过基类指针或引用,可以操作不同类型的派生类对象,实现代码的复用。
- 扩展性:新增派生类时,不需要修改依赖于基类的代码,只需要确保新类正确重写了虚函数。
- 解耦:多态允许程序设计更加模块化,降低类之间的耦合度。
注意事项:
- 只有通过基类的指针或引用调用虚函数时,才会发生多态。
- 如果直接使用派生类的对象调用函数,那么调用的是派生类中的版本,而不是基类中的版本。
- 多态性需要运行时类型信息(RTTI),这可能会增加程序的开销。
纯虚函数
您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
纯虚函数是没有实现的虚函数,在基类中用 = 0 来声明。
纯虚函数表示基类定义了一个接口,但具体实现由派生类负责。
纯虚函数使得基类变为抽象类(abstract class),无法实例化。
特点:
必须在基类中声明为 = 0
,表示没有实现,子类必须重写。
抽象类:包含纯虚函数的类不能直接实例化,必须通过派生类实现所有纯虚函数才能创建对象。
接口定义:纯虚函数通常用于定义接口,让派生类实现具体行为。