多态是指同一个方法可以根据上下文的不同而表现出不同的行为。多态性使得可以使用统一的接口来处理不同类型的对象,而无需关注对象的具体类型。多态可以通过虚函数(Virtual Function)来实现,在运行时动态确定使用哪个函数版本。多态可分为两类:1、静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名。2、动态多态: 派生类和虚函数实现运行时多态。
静态多态是在编译时确定函数调用的具体版本。它通过函数重载(Function Overloading)和运算符重载(Operator Overloading)来实现。在静态多态中,编译器根据被调用函数的参数类型或操作符的类型,在编译时就确定了要调用的具体函数或操作符重载的版本。因此,静态多态的解析发生在编译阶段,也被称为早绑定(Early Binding)或静态绑定(Static Binding)。
动态多态是在运行时确定函数调用的具体版本。它通过虚函数(Virtual Function)和函数重写(Function Overriding)来实现。在动态多态中,编译器在编译时无法确定要调用的具体函数版本,只知道调用的是基类的函数,而具体调用哪个函数版本由实际调用对象的类型决定。因此,动态多态的解析发生在运行时,也被称为晚绑定(Late Binding)或动态绑定(Dynamic Binding)。
实现多态存在两个必要条件:
继承关系:需要至少有两个类之间存在继承关系,其中一个类是基类(父类),另一个类是派生类(子类)。
虚函数:在基类中定义一个虚函数,用关键字
virtual
进行声明。派生类可以对虚函数进行重写(覆盖)。
函数重载是指在同一个作用域内,允许定义多个同名函数,但这些函数的参数个数、函数类型或顺序可以不同,函数重载属于静态多态的一种。
class Test{
static int add(int a,int b);
};
int add(int a,int b,int c){
return a+b+c;
}
double add(double a,double b){
return a*b;
}
运算符重载(Operator Overloading)是一种特殊的函数重载,允许在自定义的类中重新定义和重新实现运算符的行为。通过运算符重载,可以使得类的对象在使用类似于内置类型的运算符时表现得类似于预定义的操作。C++中可以重载的运算符包括算术运算符、关系运算符、逻辑运算符、赋值运算符等。通过重载运算符,可以自定义类的操作,让其支持相应的运算符操作。
值得注意的是:运算符函数的重载格式遵循一定的规则,具体取决于要重载的运算符。
返回类型 operator 运算符名称() const;
//或者
返回类型 operator 运算符名称();
//此外还有二元运算符重载
返回类型 operator 运算符名称(const 类型& operand) const;
//或者
返回类型 operator 运算符名称(const 类型& operand);
#include
#include
using namespace std;
class Complex{
private:
double m_real; //实部定义
double m_image;//虚部定义
public:
//构造函数初始化
Complex(double real,double image):m_real(real),m_image(image){}
//运算符重载
double operator+(const Complex& operand)const{
double real_result = pow((m_real - operand.m_real),2.0);
double image_result = pow((m_image - operand.m_image),2.0);
double result = sqrt(real_result+image_result);
return result;
}
};
通过对“+”号的运算符重载,将两个复数之间的距离给求出来,当调用+号时得到的结果是两复数之间的距离。
int main(){
Complex a(2.0,3.0);
Complex b(4.0,5.0);
double distance = a + b;
cout << "'+'号重载后,a、b两复数间的距离为: " << distance << endl;
return 0;
}
运行结果:
动态多态通过派生类和虚函数实现运行时多态。在C++中,使用关键字 virtual
声明一个成员函数为虚函数,该函数可以在派生类中被重写。当有一个基类指针或引用指向派生类对象时,通过调用虚函数可以在运行时动态地确定要调用的函数。
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容。
class Base {
public:
virtual returnType functionName(parameters) {
// 函数体
}
};
returnType
:指定函数返回值的数据类型。functionName
:虚函数的名称。parameters
:指定函数的参数列表。
纯虚函数(Pure Virtual Functions)是在基类中声明的虚函数,它没有具体的实现,只是作为接口的定义,要求派生类必须实现该函数。基类中包含纯虚函数的类被称为抽象类(Abstract Class),抽象类无法实例化,只能作为其他类的基类使用。派生类必须提供纯虚函数的具体实现,否则派生类也会被视为抽象类。
class Base {
public:
virtual returnType functionName(parameters) = 0;
};
要声明一个函数为纯虚函数,需要在基类中使用
virtual
关键字进行声明,并在函数声明的末尾加上= 0
。
returnType
:指定函数返回值的数据类型。functionName
:纯虚函数的名称。parameters
:指定函数的参数列表。
父类指针或引用指向子类对象,函数返回值类型 函数名 参数列表 完全一致进行重写。
//创建基类
class AbstrctDrinking{
public:
virtual void Boil() = 0; //纯虚函数 特点:无法实例化对象,拥有纯虚函数的类称为抽象类
virtual void Brew() = 0;
virtual void PourInCup() = 0;
virtual void PutSomething() = 0;
//规定流程
void MakeDrinking(){
Boil();
Brew();
PourInCup();
PutSomething();
}
};
//创建子类继承基类,并重写基类纯虚函数
class Coffee : public AbstrctDrinking{
virtual void Boil(){
cout << "将水煮开" <
//定义父类指针
AbstrctDrinking *drink = NULL;
//指向子类
drink = new Coffee;
drink->MakeDrinking();
//使用完后进行内存释放
delete drink;
drink = NULL;