前言
本文会帮您认识到c++的多态是什么
帮助您在C++ 的路上越走越远
?
一、重载,重定义,重写的区别与使用
1.1 重载:
重载就是相同函数名的函数,不同参数,所调用的函数也不同
void print()
{
cout<<"No.1 print"<<endl;
}
void print(int a)
{
cout<<a<<endl;
}
//像这种相同函数确有不同的参数和行为的就是重载
1.2 重定义
重定义就是子类继承于父类,在正常情况下(不存在虚函数),父类和子类拥有相同的成员函数,
这时,父类的对象用的是父类的成员函数,子类的对象用的是子类的成员函数
但是,如果用父类的指针new一个子类对象呢?
这时会调用哪一个成员函数?
其实很简单,看下面的代码示范,这就是重定向问题
当? MM*pM=new Boy;时候pM里的print()就被重定向为父类的成员函数
当看见这种没有虚函数的正常写法时候,MM*pM=new Boy;就看对象指针的类型是什么就是哪个类的成员函数
#include<iostream>
using namespace std;
class MM
{
public:
void print()
{
cout<<"MM::print"<<endl;
}
class Boy:public MM
{
public:
void print()
{
cout<<"Boy::print"<<endl;
}
int main()
{
MM mm;
mm.print();//输出的是MM::print
Boy boy;
boy.print();//输出的是Boy::print
MM*pM=new Boy;
pM.print(); //输出的是MM::print
return 0;
}
1.3 重写
重写其实就是多态,重写就是跟重定向有点区别,重写是像刚刚的那种情况下,
MM*pM=new Boy;这时候pM.print()就是用的子类的成员函数
ps:重写固如其名,就像是重新写了这个函数一样,
但是需要注意!!不代表这个函数被改变,就像是所调用的作用域不同而已
如果pM.MM::print()是可以使用MM里的print;
但是这么写太麻烦,也不是重写的精髓
这时候可以pM=&MM;这时候访问的就是MM里面的print
代码如下
#include<iostream>
using namespace std;
class MM
{
public:
virtual void print()
{
cout<<"MM::print"<<endl;
}
class Boy:public MM
{
public:
void print()
{
cout<<"Boy::print"<<endl;
}
int main()
{
MM mm;
mm.print();//输出的是MM::print
Boy boy;
boy.print();//输出的是Boy::print
MM*pM=new Boy;
pM.MM::print(); //输出的是MM::print
pM.print();//输出的是子类的Boy::print
pM=&MM;
pM.print();//输出的是父类的MM::print
return 0;
}
二、多态的概念
我们刚刚已经了解重写是什么,其实重写就是多态
多态就是因为赋值的不同,而导致的相同行为的不同结果,把这一现象叫做多态(重写)
1.多态的必要因素
?1.父类必须存在virtual?
2.子类必须存在同名函数
3.必须存在这样非正常情况下的指针使用,比如MM*pM=new Boy;
2.虚函数的概念及注意事项
1.虚函数就是函数前加virtual
2.必须发生在父类和子类之间
3.父类和子类的原型函数必须是完全相同的,
4.使用virtual声明之后的才能实现多态(如果不使用virtual,那叫做重定义)
5.虚函数从父类被继承,子类的同名函数也会是虚函数,无论写没写virtual
虚函数被继承多少次还是那个虚函数,这是血脉!
三、虚析构函数
这个点极其重要
如果不写虚析构函数
子类对象初始化父类的指针的时候,会引发析构问题
这时候需要在父类里写一个析构函数并在前面加上virtual
代码如下:
class MM
{
public:
virtual~MM()
{
cout << "MM 析构函数" << endl;
}
void print()
{
cout << "MM::print" << endl;
}
virtual void printVirtual()
{
cout << "MM::printVirtual" << endl;
}
protected:
};
class Boy:public MM
{
public:
~Boy()
{
cout << "Boy 析构函数" << endl;
}
void print()
{
cout << "Boy::print" << endl;
}
virtual void printVirtual()
{
cout << "Boy::printVirtual" << endl;
}
protected:
};
int main(){
MM* pObject = new Boy;
pObject->printVirtual();
delete pObject;
return 0;
}
注意事项:
1.有虚析构函数没有虚构造函数 2.父类要存在一个虚析构函数
总结
这就是多态的基础
学好这些接下来才能探究纯虚函数表和抽象类
如果这篇文章帮助到了您,还请关注一下哦亲
?
|