首先上一段代码:
#include <iostream>
using namespace std;
class Demo{
public:
virtual void prin(){
cout<<"woshi"<<endl;
}
};
class Lidemo : public Demo{
public:
void prin(){
cout<<"wo"<<endl;
}
};
int main(){
Demo demo ;
Demo* lidemo = new Lidemo();
demo.prin();
lidemo->prin();
return 0;
}
静态多态:
int func(int a,int b,int c){
return a + b + c;
}
int func(int a,int b){
return a-b;
}
double func(double a,int b){
return a-b;
}
int main(){
cout<<func(1,2,3)<<endl;
cout<<func(1,2)<<endl;
cout<<func(1.2,2)<<endl;
return 0;
}
静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数
动态多态:在程序运行时根据基类的引用(指针)指向的对象来确定自己具体该调用哪一个类的虚函数。
动态多态的条件:
●基类中必须包含虚函数,并且派生类中一定要对基类中的虚函数进行重写。
●通过基类对象的指针或者引用调用虚函数。
重写 :
(a)基类中将被重写的函数必须为虚函数,否则派生类还是会调用基类中没有被重写的函数
(b)基类和派生类中虚函数的原型必须保持一致(返回值类型,函数名称以及参数列表),协变和析构函数(基类和派生类的析构函数是不一样的)除外
(c)访问限定符可以不同
不能定义为虚函数的函数:
1)友元函数,它不是类的成员函数
2)全局函数
3)静态成员函数,它没有this指针
3)构造函数,拷贝构造函数,以及赋值运算符重载(可以但是一般不建议作为虚函数)
析构函数必须定义为虚函数的原因:
基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。
基类指针可能指向派生类,当delete
的时候,如果不定为虚函数,系统会直接调用基类的析构函数,这个时候派生类就可能有一部分没有被释放,造成内存泄漏。
若定义为虚函数构成多态,那么就会先调用派生类的析构函数。
参考链接:
https://blog.csdn.net/weixin_42678507/article/details/89414998
https://blog.csdn.net/qq_39412582/article/details/81628254