重载
重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
函数重载要求:
1.在同一个作用域内(同一个类中)
2.函数名字相同
3.参数列表不同:个数,类型,顺序
4.返回值不同不做为重载条件
重定义
重定义实际上是同名隐藏:在派生类中定义基类中存在的函数,派生类对象就只能访问自己的函数,而不能访问基类的同名函数(除非进行作用域扩展声明)重定义同样可以增强程序的可读性,减少函数名的数量,更重要的是它可以让相同的方法在不同派生类中有不同的实现避免了在基类中过多的存在重载。
重定义要求:
1.在不同的作用域内(原函数在基类中,重定义函数在派生类中)
2.函数名字相同(只有这一个要求)
多态
多态
目前C++中根据确定调用具体函数的时期有以下两种多态:
#静态多态
静态多态是在编译时根据函数的参数列表确定调用的具体函数即函数重载
class A{
public:
void f() {cout<<'A'<<endl;}
void f(int i) {cout<<'A'<<i<<endl;}
};
#动态多态
动态多态是运行时确定调用的具体函数
动态多态是通过虚函数实现的。
#虚函数
在函数前加上virtual关键字就会变成虚函数,派生类继承之后该函数之后无需加上virtual也会自动变成虚函数
class Shape{
public:
virtual void getArea(int i) { //虚函数
cout<<"Shape"<<endl;
}
};
class Square: public Shape{
public:
//using Shape::toString;
void getArea(int i) { //虚函数
cout<<"Square"<<endl;
}
};
class Circle: public Shape{
public:
//using Shape::toString;
void getArea() { //虚函数
cout<<"Circle"<<endl;
}
};
这时我们就可以通过一个公共的接口来调用所有派生类的getArea()方法:
void getArea(Shape &p){
p.getArea();
}
int main()
{
Square s;
Circle c;
getArea(s);//结果为Square
getArea(c);//结果为Circle
}
这个接口可以是基类的指针,也可以是基类的引用。
根据上面的介绍我们可以看出重载,重定义和多态最根本的目的都是为了在面向对象的编程中实现一种动态的特性即同一个功能,可以有不同的实现,根据对象类型可以调用不同的实现。
关于为什么基类的指针指向派生类对象可以访问派生类的虚函数以及虚函数到底是什么?在这里不做详细解释
大家可以看我的博文:https://blog.csdn.net/mxy568767179/article/details/106139227
关于重定义和多态的区别大家可以看我的博文: