[C/C++]覆盖与隐藏

  • ①类的名字查询逻辑:前后有继承关系的类,其作用域实际上是嵌套的,即虽然我们写成两个类,父类和子类,看上去好像是分离的,实际上,他们就是另一种我们常见的类的关系,就是嵌套类。当我们申请了一个子类的对象,调用其中的一个继承而来的公有函数的时候,编译器实际上是首先在子类中根据函数的名称进行查找,查找不到的话,再到他的上一层的作用域中进行查找的,这样一直向上嵌套的查找一直到基类,所以基于这种查找逻辑就可能引发一个问题,就是按照名字来查找,而完全不去看后面的参数列表的话,那么当在子类和父类都定义相同名字,而不同参数的函数的时候,就会出现问题,到底是继续查查看父类还是就是直接用子类了?C++提供了两种机制,一种是虚函数机制,如果用virtual声明成了虚函数,即走动态绑定逻辑,如果不是虚函数,即这个名字不在虚函数列表中,则走普通逻辑,因此引发出了两种进一步的操作,即覆盖和隐藏。
  • ②覆盖:覆盖的意思其实就是对于虚函数在子类中进行重写,这种写法其实和编译器的查找逻辑就没有关系了,程序在运行的过程中去寻找那个函数的入口地址,这个可以认为在编译阶段只是检查一下有没有这个函数就行了,在执行阶段,其实完全按照执行阶段的逻辑在运行,这种方式称为覆盖,可以认为是基于实际的,实际是哪个内存对象,他的虚函数列表中实际是什么函数,就调用什么函数。
  • ③隐藏:如果不是虚函数,是普通函数,这个时候就走前面的查找逻辑了,因此子类中的同名函数会隐藏父类中的函数,如果同样用父类指针指向一个子类对象,这个时候是非虚函数,并且子类中有实现这个函数,那么还是先从内层的开始调用即调用子类的,但是区别在于,如果在子类中的函数参数列表和调用的参数不同,这个时候会报错,而不是再去父类中寻找有没有对应的参数列表的函数。④总结一下的话,对于非虚函数,编译器匹配实际上由两轮逻辑,第一轮,通过名称来确定类的域,完全通过名字来确定,所以这个称为隐藏确定下来以后,父类的子类的就不看了,第二轮是在这个域中匹配对应的参数列表最最匹配的函数,这个其实是重载的工作,和前面的匹配工作没有什么关联了,主要就是这个逻辑。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章