当this指针成为指向之类的基类指针时,也能形成多态
this指针:
1)对象中没有函数,只有成员变量
2)对象调用函数,通过this指针告诉函数是哪个对象自己谁。
#include<iostream> using namespace std; class Shape { public: //void cal_display(Shape* this) void cal_display(){ display(); this->display(); } private: ; }; class Circle:public Shape { private: void display(void){ cout << "this is a Circle!" << endl; } }; int main() { Circle c1; //使用c1对象调用cal_display() 继承自基类 // 在c1对象中调用 cal_display()函数 传递 指向子类对象的基类指针给 虚函数display() 形成多态 c1.cal_display(); // 当提供接口调用 成员函数时 传递this指针 当这个指针属于子类对象时 遇到虚函数 就会形成多态 ; }
2 多态:
[将子类对象的指针赋值给基类类型的指针],通过虚函数形成多态,
虚函数的调用是通过虚函数表指针来实现的,
下面这段话来源于:http://www.cnblogs.com/cswuyg/archive/2010/08/21/1805153.html
四、延伸
忽然想到了C++的多态,一句话“将子类类型的指针赋值给父类类型的指针”,多态是通过虚函数实现。对虚函数及其相关内容的原理、详细理解就不细说了。说下我的简单理解,有一个基类A和子类B、C,有一个函数以基类A的指针为参数,然后在函数里头通过指针调用基类的成员函数。假如这个被调用的基类成员函数不是虚函数,那么是不可能实现多态的,因为翻译成汇编指令的时候,调用成员函数的这个地方是一个call指令,然后这个call指令跳到某个地方去执行,这是一个固定了的地址。通过定义为虚函数,调用成员函数的这个地方是通过虚函数表指针来确定调用哪个函数的,而虚函数表指针就放在对象的地址空间中,如果对象变了,那么虚函数表指针也变了,调用的函数也就不同了。对于那个以基类A的指针为参数的函数,指针即是对象的地址,如果传递的地址是子类B或者C的对象的地址,那么虚函数表指针也就不同了,调用的成员函数也就不同了。
这就是多态,这种多态使得调用同一个函数,因为传递参数的不同而显示出差异,参数可以是基类对象或者众多不同的子类对象。它们的差异是类与类之间的。
有虚函数的对象的内存布局,比没有虚函数的对象多了一个指向虚函数表的指针。因为虚函数的调用是通过虚函数表指针来实现的,所以有了多态。再考虑一下C++的this指针,一个类中的成员函数,依据this指针来区分不同的对象,也就是说根据this指针实现了访问不同的对象的成员变量。
这是否也是多态的一种表现?这里所说的多态已经不是那个“父类指针指向子类对象”的教条了,而是体现在同一个类的不同对象之间,调用同一个成员函数,依据参数“this指针”来实现访问不同的对象的成员变量。成员函数访问成员变量,在编译期无法确定它访问的成员变量在哪一个地址的,只有到了运行期依据this指针才能确定访问的地址。这一点很类似于类的多态:以基类指针为参数的函数里调用了某个基类的虚成员函数,在编译期无法确定程序运行时调用的会是哪个类的对象,只有到了运行期才确定会调用哪个类的对象。
this指针识别了同一个类的不同的对象,换句话说,this指针使得成员函数可以访问同一个类的不同对象。再深入一点,this指针使得成员函数会因为this指针的不同而访问到了不同的成员变量。这也是多态吧,只是它是必然存在的多态,这种多态跟基类与派生类之间的多态是不同级别的多态,它不像一般的多态可以通过对使用虚函数的选择来取舍,它是一个类对应多个对象、多个对象共享一份成员函数代码带来的必然结果。
当this指针成为指向之类的基类指针时,也能形成多态的更多相关文章
- 派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good
大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...
- c++ 动态判断基类指针指向的子类类型(typeid)
我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...
- c++基类指针指向继承类调用继承类函数
类里面重载运算符>>, 需要使用友元函数,而友元函数,不能作为虚函数. 所以,基类指针无法直接调用继承类里重构的 >> ; 使用类转换,能解决掉,基类指针 调用 继承类 ...
- C++获取基类指针所指子类对象的类名
我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 关键字 typeid, ...
- C++ 基类指针,子类指针,多态
基类指针和子类指针之间相互赋值(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,C++编译器将自动进行类型转换.因为子类对象也是一个基类对象. (2)将基类指针赋值给子类指针时,需要进行强制类 ...
- 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?
五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...
- C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
- C++ 基类指针和子类指针相互赋值
首先,给出基类animal和子类fish [cpp] view plaincopy //======================================================== ...
- 图像处理中创建CDib类时无法选择基类类型时怎么办
图像处理中创建CDib类时无法选择基类类型时怎么办? 类的类型选择Generic Class 在下面的篮筐里输入CObject就行了
随机推荐
- ASP.NET Cache缓存的使用
ASP.NET Cache是提升系统性能的重要方法,它使用了“最近使用”原则(a least-recently-used algorithm).在数据库访问中经常会用到Cache保存数据库数据. 1. ...
- 百度分享和bshare
社会法社交分享组件bshare http://www.bshare.cn/ 百度share也不错
- 使用XV-11激光雷达做hector_slam
大家在学习ROS中不可避免需要使用激光雷达,高精地图.实时定位以及障碍物检测等多项技术,而这些技术都离不开光学雷达的支持,但是呢雷达这真是太贵了,大部分人是负担不起(实验室.研究所土豪可以略过),但是 ...
- Avro之一:Avro简介
一.引言 1. 简介 Avro是Hadoop中的一个子项目,也是Apache中一个独立的项目,Avro是一个基于二进制数据传输高性能的中间件.在Hadoop的其他项目中例如HBase(Ref)和Hiv ...
- docker 及 linux 初接触
3天来净折腾这俩东西了,总结一下(很多都是同事给出的解释,先不保证正确性): 1.docker 里的images 和 container images 类似系统盘,container类似用系统盘装起来 ...
- 命令行调用远程dubbo服务
有时需要对dubbo服务做个简单的测试,或者想看下某个dubbo服务类所提供的方法,可以直接在命令行通过telnet的方式来查看和调用dubbo服务,方法如下: telnet 127.0.0.1 20 ...
- MFC学习(二)
WinApp封装了程序的主入口WinMain,WinMain就和C语言的main函数地位一样,是Win32程序的入口.在MFC的封装中,一个程序启动,Windows调用WinMain,这个WinMai ...
- 完全卸载oracle11g步骤:
完全卸载oracle11g步骤:1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务.2. 开始->程序->Oracle - OraHome ...
- 参数传递中编码问题(Get/Post 方式)(三)
自己总结的: GET方式: 1.提交方式为GET时,数据是放在请求HEADER头中的,且将数据与URL拼接后,浏览器会对拼接后的url进行编码,编码方式为浏览器默认的编码, ...
- java rest jax-rs 漫谈
rest是什么 REST是英文RepresentationalState Transfer 的缩写,有中文翻译为“具象状态传输”.REST 这个术语是由 RoyFielding 在他的博士论文< ...