目录
1.静态多态 :静态多态的,基于函数重载和模板。
2.动态多态: 用虚函数实现(在具有继承体系的类中(至少基类和派生类,即一层派生))。
1.函数重载实现静态多态:
重载的原则:
(1):函数名称必须要相同。
(2):函数的参数列表必须不同,包括:参数类型不同、参数个数不同、参数顺序不同。
(3):函数的返回类型可以相同也可以不相同(不影响,不能作为依据)。
函数重载示例:
#include<iostream>
using namespace std;
void print(int a, int b)
{
cout << "调用print(int a,int b)" << endl;
}
//int print(int a, int b){} //错误,无法重载
void print(int a, int b, int c)
{
cout << "调用print(int a,int b,int c)" << endl;
}
void print(int a, double c)
{
cout << "调用print(int a,double c)" << endl;
}
void print(double c, int a)
{
cout << "调用print(double c,int a)" << endl;
}
void print(double a, char c)
{
cout << "调用print(double a,char c)" << endl;
}
int main()
{
print(1, 2); //调用print(int a,int b)
print(2, 3, 4); //调用print(int a,double c)
print(5, 2.1); //调用print(int a,double c)
print(2.1, 5); //调用print(double c,int a)
print(2.1, 'c'); //调用print(double a,char c)
return 0;
}
用函数重载结果:
2.虚函数实现动态多态:使用基类的指针或引用来指向派生对象。
用虚函数的示例:
#include<iostream>
using namespace std;
class Base
{
public:
Base() = default;
virtual void Base_display(){}
virtual void print()
{
cout << "调用基类的print函数" << endl;
}
void PointerType()
{
cout << "基类的PointerType函数" << endl;
}
virtual~Base()
{
cout << "基类的析构函数" << endl;
}
};
class Derived :public Base
{
public:
Derived() = default;
//override关键字的作用是在写重写基类的虚函数判断虚函数是否重写正确,例如虚函数Base_display()
//当在这基类的书写中,假如Base_display写错了,当其后没有加override关键字时,编译器不会报错,
//会认为是Derived类的成员函数,而不是基类虚函数Base_display()的重写,若加override后,Base_display书写错误
//编译器将会报错
void Base_display() override{}
//void Base_display() //正确,是Derived的成员函数
//void Base_display1() override //错误 override关键会检查Base_display是否书写正确
void print()override
{
cout << "调用派生类的print函数 " << endl;
}
void PointerType()
{
cout << "派生类的PointerType函数" << endl;
}
~Derived()
{
cout << "派生类的析构函数" << endl;
}
private:
int random_{ 0 };
};
int main()
{
Base* base = new Derived; //基类指针指向派生类对象
base->print(); //调用派生类的print函数
base->PointerType(); //基类的PointerType函数
delete base;
cout << "-------------" << endl;
base = new Base; //基类指针指向基类对象
base->print(); //调用基类的print函数
base->PointerType();//基类的PointerType函数
delete base;
//基类有两个虚函数(Base_display,print),但只计算一个虚函数指针的大小
cout << "sizeof(Base)=" << sizeof(Base) << endl; //32位系统下,为4(虚函数指针的大小)
cout << "sizeof(Derived)=" << sizeof(Derived) << endl; //32位系统下,为8(虚函数的大小和一个int型变量)
return 0;
}
用虚函数的结果:
当我们写程序时,定义了自己想要的构造函数,默认的构造函数将不会有,如果当我们实例化对象时(不传参数,即调用默认的构造函数)将会报错,此时只能自己再定义出默认的构造函数Base(){}, 加个函数体 ,或者就用Base() = default; 这是说明即使定义类其他构造函数,默认的构造函数将会保留。
3.关于用到的overide关键字
override关键字的作用是在写重写基类的虚函数判断虚函数是否重写正确,例如虚函数Base_display(), 当在这书写中,假如Base_display写错了,当其后没有加override关键字时,编译器不会报错, 会认为是Derived类的成员函数,而不是基类虚函数Base_display()的重写,若加override后,Base_display书写错误的话,编译器将会报错。
加上override关键字后,能避免这样的错误,减少bug。