C++多态性的分析之赋值兼容
2014-07-31 20:01
309 查看
多态性可以简单地概括为“一个接口,多种方法”,是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为。在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体,也就实现了“一个接口,多种方法”。
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用在编译器编译期间就可以确定函数的调用地址并生产代码,那就是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
那么多态的作用是什么呢?封装可以使得代码模块化,继承可以扩展已存在的代码,它们的目的都是为了代码重用。而多态的目的则是为了接口重用,也就是说不论传递过来的究竟是哪个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。这其中涉及到赋值兼容的问题,下面我们来着重讨论它。
从表面上看,赋值兼容规则是派生类对象在起顶替基类对象的作用,但实质上,是派生类对象成员中的原基类成员组在起顶替作用。对赋值兼容规则应做如下实质理解。
1、公有派生类对象y赋值给基类对象x
把公有派生类对象y的原基类成员组各成员的值分别赋给了基类对象x的各对应成员。赋值完毕,派生类对象y和基类对象x各有各自的存储空间,各自独立为政,各不相干。
2、用公有派生类对象地址&y初始化或赋值给基类指针p
把公有派生类对象y的原基类成员组的地址值赋给了基类指针p。谁的地址赋给指针,指针就指向谁。因此,基类指针p实际是指向了派生类对象y的原基类成员。以后若遇到,比如访问p->show()函数,可认为这就是访问派生类对象y的原基类成员的show。因此当用这个基类指针p对派生类成员进行访问时,只限于访问派生对象y的原基类成员组成员,而不能访问这些成员之外的别的成员。若这个基类指针p经强迫类型转换为派生类指针(Y*)p后,就可作为派生类指针使用,就可访问派生类对象y所有各个成员了。
3、用公有派生类对象y初始化基类别名r
用公有派生类对象y的原基类成员组初始化基类别名r。谁给别名初始化,别名就属于谁。因此,这别名是派生类对象y的原基类成员组的别名,或者说别名x的实名是派生类对象y的原基类成员组,访问别名就是访问实名,比如,以后若遇到要访问x.show()函数,则可认为实际就是访问派生类对象y的原基类成员组的show函数。因此,当用这个基类别名r对派生类成员进行访问时,只限于访问派生类对象y的原基类成员组的成员,而不能访问这些成员之外的别的成员。若这个基类别名r经强迫类型转换为派生类别名(Y&)r后,就可作为派生类别名使用,就可以访问派生类对象y所有各个成员了。以后,若把派生类对象地址赋给了基类指针,我们就可以简单地说,基类指针指向了派生类对象。但要明白,实质是基类指针指向了派生类对象的原基类成员组,对别名也类似。
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用在编译器编译期间就可以确定函数的调用地址并生产代码,那就是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
那么多态的作用是什么呢?封装可以使得代码模块化,继承可以扩展已存在的代码,它们的目的都是为了代码重用。而多态的目的则是为了接口重用,也就是说不论传递过来的究竟是哪个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。这其中涉及到赋值兼容的问题,下面我们来着重讨论它。
从表面上看,赋值兼容规则是派生类对象在起顶替基类对象的作用,但实质上,是派生类对象成员中的原基类成员组在起顶替作用。对赋值兼容规则应做如下实质理解。
1、公有派生类对象y赋值给基类对象x
把公有派生类对象y的原基类成员组各成员的值分别赋给了基类对象x的各对应成员。赋值完毕,派生类对象y和基类对象x各有各自的存储空间,各自独立为政,各不相干。
2、用公有派生类对象地址&y初始化或赋值给基类指针p
把公有派生类对象y的原基类成员组的地址值赋给了基类指针p。谁的地址赋给指针,指针就指向谁。因此,基类指针p实际是指向了派生类对象y的原基类成员。以后若遇到,比如访问p->show()函数,可认为这就是访问派生类对象y的原基类成员的show。因此当用这个基类指针p对派生类成员进行访问时,只限于访问派生对象y的原基类成员组成员,而不能访问这些成员之外的别的成员。若这个基类指针p经强迫类型转换为派生类指针(Y*)p后,就可作为派生类指针使用,就可访问派生类对象y所有各个成员了。
3、用公有派生类对象y初始化基类别名r
用公有派生类对象y的原基类成员组初始化基类别名r。谁给别名初始化,别名就属于谁。因此,这别名是派生类对象y的原基类成员组的别名,或者说别名x的实名是派生类对象y的原基类成员组,访问别名就是访问实名,比如,以后若遇到要访问x.show()函数,则可认为实际就是访问派生类对象y的原基类成员组的show函数。因此,当用这个基类别名r对派生类成员进行访问时,只限于访问派生类对象y的原基类成员组的成员,而不能访问这些成员之外的别的成员。若这个基类别名r经强迫类型转换为派生类别名(Y&)r后,就可作为派生类别名使用,就可以访问派生类对象y所有各个成员了。以后,若把派生类对象地址赋给了基类指针,我们就可以简单地说,基类指针指向了派生类对象。但要明白,实质是基类指针指向了派生类对象的原基类成员组,对别名也类似。
相关文章推荐
- C#与C++多态性对比分析1
- C++赋值兼容规则和多态
- 【总结】C++基类与派生类的赋值兼容规则
- C++中的继承(3)作用域与重定义,赋值兼容规则
- C++中的继承(3)作用域与重定义,赋值兼容规则
- C++的赋值兼容规则
- C++多态赋值兼容&&多态
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- 【总结】C++基类与派生类的赋值兼容规则
- C++ 同名隐藏和赋值兼容规则
- C++与C#中包含多态性分析
- C++虚函数多态性的实现与分析+虚继承的实现与分析
- C++学习之赋值兼容规则以及在私有、保护继承下的强制转换
- c++学习之赋值兼容规则
- [c++]基类对象作为函数参数(赋值兼容规则)
- C++赋值兼容原则理解
- C++ 多态性分析
- 赋值兼容规则——学习c++笔记
- C++基础:同名隐藏与赋值兼容规则
- C++:同名隐藏和赋值兼容规则