• C++赋值兼容原则理解


    –赋值兼容原则(派生类对象是基类对象,反之不成立)
    –基类指针强制转换成派生类指针
    –派生类中重定义基类成员(同名覆盖)

    假设, 一个基类 "普通人", 一个派生类 "超人".

    1) 赋值兼容原则(派生类对象是基类对象,反之不成立)

    超人是人吧, 但不是每个人都是超人.
    现在我要找一个普通人来干活.

    Man* p = new Man;       // OK, p指向了一个普通人对象.
    Man* p = new SuperMan;  // 也OK, 虽然有些大才小用, 但是超人确实可以胜任普通人的工作.
    
    反过来的话: SuperMan* sp = new Man; // No, 错误, 我需要一个超人, 普通人无法胜任..

    2) 基类指针强制转换成派生类指针.

    基类指针不可以直接转换成派生指针.
    因为你如果准备让普通人(基类)去做超人(派生类)的工作, 是非常危险的, 所以语法不允许.
    但是, 由(1)我们知道超人有可能隐藏在普通人之间的(指针是Man*, 但实际对象是SuperMan).
    在你确切知道他实际上是超人的时候, 那么可以使用"强制转化", 让他去做超人的事情.
    但是, 如果他真的只是普通人, 那么"强制转换"的后果是不确定的, 很可能会引发运行错误.

    Man* p = new SuperMan; // 虽然是Man*, 但实际是SuperMan.
    ((SuperMan*)p)->Fly(); // "强制转换"之后调用 Fly(飞行)函数. 
    Man* p = new Man; // 真的只是普通人. ((SuperMan*)p)->Fly(); // 语法可以通过, 但是运行阶段很可能会出现莫名其妙的错误.

      

    (3) 派生类中重定义基类成员
    成员函数前加virtual表示虚函数, 意味着派生类可能会有自己的特殊实现.
    比如说"看"Look这个动作, 普通人只是用肉眼看, 但是超人用红外线看东西.

    class Man{
    virtual void Look()
    {   
    // 正常人看的代码.
    }
    };
    class SuperMan: public Man { virtual void Look() { // 红外线 } };

    SuperMan中的Look前面加不加virtual都可以, 意思不会变.

    Man* p = new SuperMan;
    p->Look() // 红外线, 虽然用Man*调用函数, 但是由于是虚函数, 会自动定位到SuperMan::Look上。
    

      

    很有意思的打比方,过目不忘(看过就不会忘)。

    转载自:https://blog.csdn.net/cs494208907/article/details/11920971

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    redis中save和bgsave区别
    scrapy生成json中文为ASCII码解决
    mysql数据库,创建只读用户
    memcached命令行、Memcached数据导出和导入
    Memcache 查看列出所有key方法
    Elasticsearch5.x 引擎健康情况
    docker容器创建MariaDB镜像
    大文本数据排序
    换行符 和回车符
    索引与文本文件
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/10375370.html
Copyright © 2020-2023  润新知