博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++父类指针强制转为子类指针后的测试(帮助理解指针访问成员的本质)(反多态)...
阅读量:5354 次
发布时间:2019-06-15

本文共 1072 字,大约阅读时间需要 3 分钟。

看下面例子:

#include "stdafx.h"

#include <iostream>

class A {  //父类

public:  

  void  f()   //普通函数

  {   

    std::cout<<"A"<<std::endl;  

  }  

  void virtual vf()   //虚函数

  {   

    std::cout<<"virtual-A"<<std::endl;  }

  };

class B : public A  //子类

{

public:  

  void  f()  

  {  

    std::cout<<"B"<<std::endl;  

  }  

  void virtual vf()  

  {   

    std::cout<<"virtual-B"<<std::endl;  

  }

   int m;  //B类的成员变量  

  B()    //在B类的构造中给成员变量赋值  

  {   

    this->m=20;  

  }

};

int _tmain(int argc, _TCHAR* argv[]) 

{  

  A *pa = new A();  //只实例化一个父类的对象,但下面要当作子类用  

  B *pb = (B *)pa; //用强制类型转换,把父类指针转化为子类指针,用这个子类指针访问子类的成员  

  pb->f();    //覆盖时,调用的是子类的函数  

  pb->vf();  //虚函数时,调用的是父类的函数,是因为虚函数表记录的是父类的方法,没有显示new一个子类,所以不会改虚函数表的内容  

  std::cout<<pb->m<<std::endl;  //结果输出的是乱码,不是20  

  //原因,要输出子类的成员变量m,但实际上pb指向的内存空间只有父类大小,所以访问的m实际上是超出了实例化的对象的范围  return 0;

}

运行结果:

总结:其实可以这样理解,根据某个类型的指针访问某个成员时,编译器会根据类型的定义, 查找这个成员(对编译器来讲成员名只是个标记)所在偏移量,用这个偏移量获取成员。 比如上面用指针pb访问成员变量m时,m对于pb来说只是个标记,说明要从pb开始偏移多少个字节才能访问到m。

上面的例子我称为“反多态”,因为,通过一个多态的指针(多态时是父类型的指针,上面的例子是子类型的指针)访问普通成员函数时访问的是子类的函数(刚好和多态相反),通过子类的指针访问虚函数时访问的是父类的函数(也刚好和多态相反)。

转载于:https://www.cnblogs.com/hnfxs/p/3192933.html

你可能感兴趣的文章
建造者模式
查看>>
ArraySort--冒泡排序、选择排序、插入排序工具类demo
查看>>
composer 安装laravel
查看>>
8-EasyNetQ之Send & Receive
查看>>
Android反编译教程
查看>>
List<string> 去重复 并且出现次数最多的排前面
查看>>
js日志管理-log4javascript学习小结
查看>>
Android之布局androidmanifest.xml 资源清单 概述
查看>>
How to Find Research Problems
查看>>
Linux用户管理
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
使用iperf测试网络性能
查看>>
图片的显示隐藏(两张图片,默认的时候显示第一张,点击的时候显示另一张)...
查看>>
Docker 安装MySQL5.7(三)
查看>>
python 模块 来了 (调包侠 修炼手册一)
查看>>
关于CSS的使用方式
查看>>
分析语句执行步骤并对排出耗时比较多的语句
查看>>
原生JS轮播-各种效果的极简实现
查看>>
计数器方法使用?
查看>>