C++学习笔记52——继承情况下类的作用域

来源:互联网 发布:html中调用js函数 编辑:程序博客网 时间:2024/05/29 03:18

1,函数调用的4个步骤

  1. 确定进行函数调用的对象、引用或指针的静态类型,静态类型决定着可以使用什么成员。比如,如果静态类型是基类指针,动态类型却是派生类指针,则该指针还是只能找到基类作用域中出现的名字;
  2. 在该类(静态类型的类)中查找函数,如果找不到,就在其基类中查找,如此循着类的继承链往上找,直到找到函数或查找完最后一个类。找不到则调用失败;
  3. 一旦找到了名字就进行常规类型检查,哪怕是对要进行动态绑定的虚函数也是如此,所以动态绑定时要求该虚函数在基类和派生类中的参数类型也要一致;
  4. 假定函数调用合法,编译器就生成代码。如果函数是虚函数,且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个版本 ,否则编译器生成代码直接调用函数。

2,重载与动态绑定的区别

  1. 对于作用域:重载出现在相同的作用域中,要么都在基类中,要么都在派生类中;动态绑定相反,虚函数必须一个出现在基类中一个出现在派生类中;
  2. 对于形参:重载的多个函数形参必须不同;动态绑定的函数形参必须相同;
  3. 对于返回类型:重载对于返回类型无要求,不能基于返回类型的不同而重载函数;动态绑定要求返回类型必须一致,或者:如果基类版本的虚函数返回类A的引用或指针,则派生类中的版本可以返回类A的派生类的引用或指针;
  4. 对于virtual:重载不要求virtual,动态绑定必须要是virtual函数才行;
  5. 对于调用方式:用对象、指针还是引用调用对重载没有影响,但是只有基类的引用或指针调用才能触发动态绑定;
  6. 重载在编译时确定,动态绑定在运行时确定;

3,基类重载,派生类继承

如果基类中有重载的成员,其被派生类继承。派生类可以重定义所继承的0个或多个版本。如果派生类重定义0个,则继承来的所有版本,派生类动能用——只要权限允许。如果派生类重定义了其中的n个版本,则该派生类就只能使用这n个版本,继承来的其他版本被屏蔽了。
所以,在不使用using的情况下,如果派生类想使用所有的版本,就只有两种方法:
  1. 重定义所有的重载版本;
  2. 一个也不重定义,这样进行名字查找的时候在派生类中找不到就自动进入基类查找了;
如果只想重定义其中的一个版本,又想使用其他的所有继承得来的版本,则使用using. using Base::fun;
一个using声明只能指定一个名字,不能指定形参表。

4,名字冲突与继承

与基类成员同名的派生类成员将屏蔽对基类成员的访问。
这里有两点要注意:
  1. 不要以为派生类中只有函数成员才能屏蔽基类中的函数成员,实际上派生类中的数据成员同样也能屏蔽基类中的函数成员,只要名字一样。名字就是名字,与是否为函数无关;
  2. 屏蔽仅仅是屏蔽,派生类仍然继承了基类中的该同名成员,并且会将该成员传递到自己的派生类中去。这种区别是有意义的,尤其是当被屏蔽的是基类中的虚函数的时候。
0 0
原创粉丝点击