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指针成为指向之类的基类指针时,也能形成多态的更多相关文章

  1. 派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good

    大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...

  2. c++ 动态判断基类指针指向的子类类型(typeid)

    我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...

  3. c++基类指针指向继承类调用继承类函数

      类里面重载运算符>>, 需要使用友元函数,而友元函数,不能作为虚函数. 所以,基类指针无法直接调用继承类里重构的 >>  ; 使用类转换,能解决掉,基类指针 调用 继承类 ...

  4. C++获取基类指针所指子类对象的类名

    我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 关键字 typeid, ...

  5. C++ 基类指针,子类指针,多态

    基类指针和子类指针之间相互赋值(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,C++编译器将自动进行类型转换.因为子类对象也是一个基类对象. (2)将基类指针赋值给子类指针时,需要进行强制类 ...

  6. 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?

    五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...

  7. C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构

    一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...

  8. C++ 基类指针和子类指针相互赋值

    首先,给出基类animal和子类fish [cpp] view plaincopy //======================================================== ...

  9. 图像处理中创建CDib类时无法选择基类类型时怎么办

    图像处理中创建CDib类时无法选择基类类型时怎么办? 类的类型选择Generic Class 在下面的篮筐里输入CObject就行了

随机推荐

  1. Spring和MyBatis整合

    前言:在前面一篇文章中,介绍了单独使用MyBatis连接orace的例子,在这里分享学习下Spring和MyBatis是如何整合的,以具体工程为例子 阅读目录: 1.环境准备 2.搭建工程 2.1.a ...

  2. nginx中在超全局变量$_SERVER中增加变量

    业务中可能会用到一些自定义的超全局变量,需要在nginx中生成的,比如,每次nginx请求的id,可以在nginx中配置 如: location ~ \.php$ { root           / ...

  3. 在Toad中导入导出数据

    一.导出数据 右键点击所要导出的表名,选择“Export   Date”     二.导入数据   一.右键点击表名,选择“import  date” 二.下一步 三.下一步 四.下一步 在oracl ...

  4. F4NNIU 学习目录 (2018-08-22)

    F4NNIU 学习目录 语言 C 语言 C 语言程序设计进阶 在线刷题 https://leetcode-cn.com/problemset/all/ 工具 Git 版本管理 在线教程 在线教程

  5. Java问题:中间件是什么

    和朋友聊天时被问到中间件是什么?一时有点语赛,感觉熟悉这个概念,但又完全不知道如何清楚的向别人讲这些. 网络上搜了一下,也没找到让自己很认可的说法,有的说非业务的技术类组件,是操作系统之上和业务逻辑之 ...

  6. Aix之 xmanager 2.0连接AIX服务器

    xmanager连接AIX服务器可以分为两种情况:1.连接IBM服务器,使用远程桌面功能进行系统维护.要求这台服务器已经安装了图形桌面,如CDE等,并启动到图形界面.在xmanager中的Xbrows ...

  7. Linux 绑定双网卡

    1.立即关闭iptables并禁用开机自启动[root@mysql01 ~]# /etc/init.d/iptables stop[root@mysql01 ~]# chkconfig iptable ...

  8. flask 之 mongodb

    查看mongod 是否启动,启动了会显示进程ID和程序名 pgrep mongod -l 查找mongod的位置whereis mongod 或locate mongod 启动mongodmongod ...

  9. Java-Runoob:Java 基本数据类型

    ylbtech-Java-Runoob:Java 基本数据类型 1.返回顶部 1. Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根 ...

  10. AngularJS:template2

    ylbtech-AngularJS: 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1.   2.  6.返回顶部   作者:ylbtech出处:h ...