一、多态性概述
面向对象的多态性可以分为4类:重载多态、强制多态、包含多态和参数多态。前面两种统称为专用多态,而后面两种称为通用多态。
包含多态 是类族中定义于 不同类中的 同名成员函数 的多态行为,主要是通过虚函数来实现。
多态的实现
多态从实现的角度来讲可以划分为两类:编译时的多态和运行时的多态。
绑定是指计算机程序自身彼此关联的过程,就是把一条消息和一个对象的方法相结合的过程。绑定工作在编译连接阶段完成的情况称为静态绑定;绑定工作在程序运行阶段完成的情况称为动态绑定。
二、运算符重载
运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。
运算符重载的实质就是函数重载。
运算符重载的规则
规则如下:
- ++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符。
- 重载之后运算符的优先级和结合性都不会改变。
- 重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
运算符的重载形式有两种,即重载为类的非静态成员函数和重载为非成员函数。运
算符重载为类的成员函数的一般语法形式为:
cpp返回类型 operator运算符(形参表) { 函数体 }
运算符重载为非成员函数的一般语法形式为:
cpp返回类型 operator运算符(形参表) { 函数体 }
返回类型 指定了重载运算符的返回值类型,也就是运算结果类型;operator 是定义运算符重载函数的关键字;运算符 即是要重载的运算符名称,必须是C++中可重载的运算符,比如要重载加法运算符,这里就写"十";形参表中给出重载运算符所需要的参数和类型。
在C++中,operator 运算符 ---> 函数
cpp
operator +
例子:复数相加
cpp
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(double r, double i) : real(r), imag(i){}
void show() const {cout << real << " + " << imag << "i" << endl;}
Complex operator +(const Complex &other) const
{
Complex ret(this->real + other.real, this->imag + other.imag );
return ret;
}
private:
double real, imag;
};
int main()
{
Complex c1(1,2);
c1.show();
Complex c2(2,3);
c2.show();
(c1+c2).show();//c1.operator +(c2).show();
cout << "Hello World!" << endl;
return 0;
}
当以非成员函数形式重载运算符时,有时需要访问运算符参数所涉及类的私有成员,这时可以把该函数声明为类的友元函数。
or 友元函数
++前 后++
效率:++i > ++i
三、虚函数
虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。
通过指针、引用来访问虚函数。
例子:选择英雄
cpp
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
class Hero
{
public:
virtual void q(){}
};
class HY : public Hero
{
void q() {cout << "the last sun" << endl;}
};
class ZZ : public Hero
{
void q() {cout << "i am butterfly" << endl;}
};
class WZJ : public Hero
{
void q() {cout << "the ice" << endl;}
};
int main()
{
Hero *p;
int n = 0;
cin >> n;
if (n == 1)
{
p = new HY;
}
else if (n == 2)
{
p = new ZZ;
}
else
{
p = new WZJ;
}
p->q();
return 0;
}
虚表
- 吸收基类成员----继承
- 改造基类成员----覆盖
- 添加基类成员
- 如果派生类的某函数,在基类没有相应的同名、同形参的函数,该函数被编译时会报错;++(如:基类不含fn7 fn8 ,所以调用这两个函数时,编译报错)++
- 全局函数不能为虚函数;
- 静态函数不能为虚函数;
- 构造函数不能为虚函数。
虚析构函数
虚析构函数的声明语法为:
cppvirtual ~类名();
如果一个类的析构函数是虚函数,那么由它派生而来的所有子类的析构函数也是虚函数。
如果有可能通过基类指针调用对象的析构函数(通过delete),就需要让基类的析构函数成为虚函数,否则会产生不确定的后果。
四、纯虚函数与抽象类
纯虚函数的声明格式为:
cppvirtual 函数类型 函数名(参数表)=0;
实际上,它与一般虚函数成员的原型在书写格式上的不同就在于后面加了"=0"。声明为纯虚函数之后,基类中就可以不再给出函数的实现部分。纯虚函数的函数体由派生类给出。
有部分是纯虚函数就是抽象类全部都是纯虚函数 就是接口类