C++多态是什么,来看这篇文章(保姆级教学)

发布于:2022-12-25 ⋅ 阅读:(897) ⋅ 点赞:(0)


前言

本文会帮您认识到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.父类要存在一个虚析构函数

总结

这就是多态的基础

学好这些接下来才能探究纯虚函数表和抽象类

如果这篇文章帮助到了您,还请关注一下哦亲