为什么会有虚函数的出现呢?这就不得不提到多态了
多态:专业的术语说就是:同一个实现接口,使用不同的实例而执行不同的操作。而简单的来说同一个事物的不同体现,比如我是老师的学生,是爸爸妈妈的女儿。
多态有什么好处:
有两个好处:
1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承
2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用,
多态实现方法的分类:
静态多态-------->函数重载https://blog.csdn.net/a15929748502/article/details/80748747
泛型编程
动态多态-------->虚函数
也就是说虚函数其实是实现动态多态的一种方法
下来我们就可以进行今天的探索了
动态多态的实现条件:
1.基类中必须存在虚基类,派生类必须重写虚基类中的虚函数。
重写时应注意:基类里的将被重写的函数必须是虚函数,
积累和派生类的原型必须一抹一样(包括返回值,函数名,参数)
注意:协变(基类(派生类)虚函数返回基类(派生类)的指针或引用)和构造函数例外
2通过基类对象的指针或引用来调用虚函数。
下面我来实现模拟一个例子
有这样一个场景,我在大街上走着,过来的如果是我的朋友小明,我应该向他打招呼“”嗨,小明“”
而如果是小红则应该打招呼“”“嗨,小红”
又有一个场景,在公共卫生间,女的上女厕,男的上男厕所
我们可以用一些代码来表示,并让大家更好地理解什么是多态,虚函数又是怎么用。方便在哪里。
class WashRoom
{
public:
void GoToManWashRoom()
{
cout<<"Man ---> Please Left"<<endl;
}
void GoToWomanWashRoom()
{
cout<<"Woman ------> Please Right"<<endl;
}
};
class Person
{
public:
virtual void GoToWashRoom(WashRoom& wc) = 0;
}
class Man:public Person
{
public:
virtual void GoToWashRoom(WashRoom& wc)
{
wc.GoToManWashRoom();
}
};
class Woman:public Person
{
public:
virtual void GoToWashRoom(WashRoom& wc)
{
wc.GoToWomanWashRoom();
}
};
最后,有哪些函数不可以做虚函数呢
1.普通函数
2.友元函数
3,静态成员函数(静态成员函数可以不通过类来调,但是虚函数一定要用类来调)
4.构造函数,拷贝函数(还没有对象,就没有指向虚表的指针,就不可以通过虚表去调用,这是一个先有鸡还是先有蛋的问题)
5.内联函数;
inline函数在编译时被展开,在调用处将整个函数替换为代码块,省去了函数跳转的时间,提高了SD,减少函数调用的开销,虚函数是为了继承后对象能够准确的调用自己的函数,执行相应的动作。
主要的原因是:inline函数在编译时被展开,用函数体去替换函数,而virtual是在运行期间才能动态绑定的,这也决定了inline函数不可能为虚函数。(inline函数体现的是一种编译机制,而virtual体现的是一种动态运行机制
注意:派生类里的析构函数最好给成虚函数。否则派生类中如有空间的开辟那么有可能造成内存泄露
运算符重载可以写成虚函数但不建议用
换句话说必须是类的成员函数
探索到这里大家应该有一定的认识了吧,下一篇我会把含有虚函数的对象模型讲给你听