当前位置: 首页 > news >正文

C++ 类的多态五(多态的语法本质分析)

//多态的语法本质分析
#include<iostream>
using namespace std;

/*
三种易混淆的多态场景
*/

class Point{
public:
    Point(int b=0){
        this->b = b;
    }

    virtual void Print(){
        cout << "父类的虚函数" << endl;
    }

private:
    int b;
};

class PointA :public Point{
public:
    virtual void Print(){
        cout << "子类重写父类的虚函数" << endl;
    }
};

void ProtectB(){
    PointA pa ;
    //场景①
    Point p1;
    p1 = pa;
    p1.Print();
    //执行p1 = pa;完成的是将子类对象中父类部分的数据拷贝到父类对象中(我并不是说子类对象中有父类对象,子类对象就是子类对象,没有父类对象)
    //这个操作并没有使父类对象在内存里变成子类对象,没有分配新的内存,p1对象所占的内存空间还是那么大,只是简单的数据拷贝
    //p1.Print();他的真身是父类对象调用自己的虚函数,那么执行的还是自己的虚函数

    //场景②
    Point p2 = pa;
    p2.Print();
    //p2不会产生多态,因为Point p2 = pa;本质上是调用了p2的默认拷贝构造函数
    //用子类对象初始化父类对象,本质上还是将子类对象中父类部分的数据拷贝到父类对象中
    //p2在内存中的大小仍然是sizeof(Point)
    //p2.Print();他的真身是父类对象调用自己的虚函数,那么执行的还是自己的虚函数

    //场景③
    //但是下面的例子是完全不同的
    PointA *pa2 = new PointA();
    Point *p3 = NULL;
    p3 = pa2;
    //这里的p3 = pa2;和上面试完全的不同 pa2是一个指针,指向一个子类对象的内存空间
    //通过 p3 = pa2;   使得父类指针p3指向了子类对象的内存空间
    p3->Print();
    //此时p3->Print();会发生多态
    

    /*
    由此得出结论:多态的语法本质是:父类指针指向了一个子类对象(c++引用本质上是一个常量指针)
    而且我认为在多态的场景中使用父类指针加法运算是危险的
    父类的步长是sizeof(Point)个大小的字节,子类的步长是sizeof(PointA),这两个对象的步长未必相同,因为子类可能添加了自己的私有属性
    例如p3++;非常危险
    */
    delete pa2;

}

void main(){
    ProtectB();
    system("pause");
}

 

相关文章:

  • C++ 抽象类一(多继承与赋值兼容性原则)
  • Mysql 备份与恢复
  • php 审核管理
  • 《Android深度探索》第八章心得体会
  • redis集群部署配置
  • 在互联网时代,你是消费者还是创造者?
  • 面向对象之设计模式大全
  • 关于win10配置MAVEN问题
  • php进阶整理
  • Bootstrap速学教程之简要介绍
  • CentOS如何查看端口是被哪个应用/进程占用
  • MFT的0x10标准属性数据结构
  • 一个简单的AXIS远程调用Web Service示例
  • 用五种以上的方式调试php
  • 使用System.Drawing.Imaging.dll进行图片的合并
  • 【技术性】Search知识
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android 架构优化~MVP 架构改造
  • CSS 提示工具(Tooltip)
  • ES6之路之模块详解
  • MQ框架的比较
  • PHP 7 修改了什么呢 -- 2
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 安装python包到指定虚拟环境
  • 分类模型——Logistics Regression
  • 普通函数和构造函数的区别
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 如何在 Tornado 中实现 Middleware
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 数据可视化之下发图实践
  • 通过调用文摘列表API获取文摘
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • !!java web学习笔记(一到五)
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (6)STL算法之转换
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (二)linux使用docker容器运行mysql
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (三分钟)速览传统边缘检测算子
  • (学习日记)2024.01.09
  • (转)setTimeout 和 setInterval 的区别
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .a文件和.so文件
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .jks文件(JAVA KeyStore)
  • .NET 事件模型教程(二)
  • .Net程序帮助文档制作
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .Net中wcf服务生成及调用
  • /usr/bin/env: node: No such file or directory