<C++>初识多态,剖析virtual关键字

熬过无人问津的日子,才有诗和远方

写在前面

        书接上文,  今天学习C++多态的知识。作为面向对象三大核心的最后一个,我们要牢记概念并深入理解多态的底层,到后面也会有很多经典的例题供我们巩固练习。话不多说,开始今天的学习!

       ✨✨ 感兴趣的同学可以订阅一下我的这个《C++入门》专栏喔~✨✨

目录

初识多态

基本概念

满足条件和使用方法 

运行效果

virtual的本质

利用开发者命令提示

小结

✨总结 


初识多态

基本概念

        多态是C++面向对象三大特性之一

多态分为两类

  • 静态多态: 函数重载 和 运算符重载属于静态多态
  • 动态多态: 派生类和虚函数实现运行时多态

静态多态和动态多态区别:

  • 静态多态的函数地址早绑定 - 编译阶段确定函数地址
  • 动态多态的函数地址晚绑定 - 运行阶段确定函数地址

满足条件和使用方法 

多态满足条件

  • 有继承关系
  • 子类重写父类中的虚函数

多态使用

  • 父类指针或引用指向子类对象

函数重写重载的比较 

重写: 函数返回值类型 函数名 参数列表 完全一致

重载:与函数返回值无关,函数名需要一致,参数列表中形参的数量,数据类型,顺序不完全相同

下面用具体代码讲解多态:

class Animal
{
public:
	virtual void eat()
	{
		cout << "吃饭饭" << endl;
	}
};
class Dog : public Animal
{
	void eat()
	{
		cout << "啃大骨头" << endl;
	}
};
class Cat : public Animal
{
	void eat()
	{
		cout << "吃小鱼干" << endl;
	}
};
void doEat(Animal &animal) 
{
	animal.eat();
}
void test01()
{
	Dog dog;
	doEat(dog);
	Cat cat;
	doEat(cat);
}

         这里把Animal类设为父类,子类Dog和子类Cat都公共继承Animal父类。父类中的eat前加了virtual关键字,那么eat函数就被叫做虚函数,这些就满足了多态的条件。此外,doEat函数的参数列表是父类的引用,那么也就满足了多态使用的父类引用或指针指向子类对象。

        这里注意一下父类引用指向子类对象,例如 Animal &animal=dog;此时的animal调用eat方法,出现的是子类重写后的内容。这是因为虽然animal是父类的数据类型,但是实际上还是属于Dog类这个子类,animal的地址和dog的地址相同,调用的方法自然是子类重写的方法。如果不加引用(&),那就变成了Animal animal=dog;那这个时候animal就是纯粹的Animal类了,调用的eat自然就会是父类的eat函数。

运行效果

        如果doEat不加引用,那么运行结果就会是:

virtual的本质

        virtual实际上是一个指针

利用开发者命令提示

        Visual Stduio提供了一个开发者命令提示的强大工具,可以让我们看清类的布局等等。

使用方法: 

1、找到”工具“并按图示点开命令行里的开发者命令提示

2、打开后是这个页面,自动跳转到需要操作的路径

3、输入 cl /d1 reportSingleClassLayoutAnimal .\多态\多态基本概念.cpp(父类布局)

在这里可以清楚的看到类Animal所占内存空间为4,因为指针占用的内存空间都是4。

vfptr这个指针指向vftable这个表,表里面存放的是函数的地址&Animal::eat,由于函数可以重写,所以前面加上了作用域来表明是哪个类的函数。

4、 输入cl /d1 reportSingleClassLayoutDog .\多态\多态基本概念.cpp(查看Dog类布局)

由于Dog类继承Animal类,所以占用空间也是4,也有指针virtual以及vfptr指针指向vftable表,只是表中的函数ear地址变为了Dog类的函数地址

5、不加virtual关键字

由于没有了指针,所以该类属于空类,默认占用1个字节的空间

小结

        通过以上图示我们知道virtual关键字可以做到函数地址的晚绑定,可以在运行时确定运行哪个类的函数,而且virtual是一个指针,他里面含有vfptr指针指向vftable表,表里存放函数地址。

✨总结 

        本篇博客希望让大家明白多态的基本使用,以及弄明白虚函数尤其是virtual关键字的含义,以便于接下来我们的多态实战的顺利进行。希望大家可以研究研究开发者命令提示,确实很新奇和强大!       

猜你喜欢

转载自blog.csdn.net/m0_58618795/article/details/125438516