目录
🎶多态的概念
比如我们在乘公交车的时候使用的公交卡,学生上面就会显示一下~~bi学生卡,老人就会bi一下,老年卡,bibi~~~。那么你有想过为什么同为一张卡为什么他的就会是学生卡,而你却往里面塞硬币呢,或者说你的卡没有bibi呢~~~。这里就涉及到多态问题,那么这么多形态它是怎么是实现的呢?
🎶多态的定义及实现
✨多态的构成条件
多态是在使用派生类对象继承了一个对象之后,基类和派生类对象同样去调用同一个函数,函数实现的功能不一样。一个比较形象的例子。比如儿子这个对象继承了父亲对象,然后这两个对象都去找母亲要零花钱,身份不一样要过的零花钱肯定就不一样了吧~~~~
✨在继承中实现多态的必要条件
- 必须通过基类的指针或者引用来调用虚函数
- 被调用的函数必须是虚函数,且派生必须和基类的虚函数完成重写
✨虚函数
被virtual修饰的类成员函数称为虚函数~~
✨虚函数重写
Exception:
派生类对象函数起那面不加virtual关键字,返回值,函数名称,参数相同。也构成重写。最好还是加上~~
- 协变:派生类对象虚函数和基类虚函数返回值不同也构成多态,称之为协变。
class Father
{
public:
virtual Father* Mom()
{
cout << "Get Out of my sight~" << endl;
return new Father;
}
};
class Son :public Father
{
private:
virtual Son* Mom()
{
cout << "My dear son" << endl;
return new Son;
}
};
- 析构函数的多态:析构函数名字不同但但是也构成多态,是因为析构函数在析构时会在底层调用destructor。做了统一处理。所以也构成协变。
这里我们看多多调用了一次基类的析构函数是因为派生类在有构造函数,或者析构函数时,基类部分的变量调用基类的构造或者析构函数~~~
✨override And final
override检查派生类是否重写基类虚函数,如果没有就报错~~~
final定义基类不可以再被继承~~~~~
✨重写,重载,隐藏的比较
🎶抽象类
在虚函数后面加上=0;那么这个函数就为纯虚函数,包含纯虚函数的类称之为抽象类,抽象类不可以实例化出对象,被继承之后派生类也不可以实例化出对象,只有派生类也重写纯虚函数才可以实例化出对象~~
🎶多态的原理
class A
{
public:
virtual void Func()
{
cout << "hello world" << endl;
}
private:
int a;
char c;
};
int main()
{
cout << sizeof(A) << endl;
return 0;
}
经过检验A类大大小为12个字节,那么肯定这里的虚函数就有占位的可能。其实就是虚函数的作用,虚函数会生成一个虚函数指针放在对象的第一个位置,那么在32位系统中指针大小为4个字节。就占用了前四个字节地址~~~
我们称a对象下面虚函数所生成的为虚函数表指针,而这个指针所指向的就是多态形成的关键所在~~~
class A
{
public:
virtual void Func()
{
cout << "hello world" << endl;
}
void Funcn(A& a)
{
a.Func();
}
private:
int a;
char c;
};
class B:public A
{
public:
virtual void Func()
{
cout << "yes" << endl;
}
};
int main()
{
A a;
a.Funcn(a);
B b;
b.Funcn(b);
return 0;
}
我们定义了一个派生类去继承基类
我们发现虽然派生类要去继承基类的成员,但是虚表指针却不是继承过来的,每个类里面都有自己的虚表指针。每个对象的虚表指指针再去调用自己的虚函数~~我自己是这样理解的。
✨summary