zoukankan      html  css  js  c++  java
  • C++赋值兼容原则

    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

  • 相关阅读:
    国内的pythoner强烈建议使用豆瓣的pypi源 zz
    python3.x中的urllib模块
    idcheck.py
    17、关于hibernate的N+1问题
    16、【转】Hibernate 原汁原味的四种抓取策略
    1、SSH的整合---->将Struts2整合到Spring中
    1、利用json2html.js处理json数据
    1、Ubuntu14.04使用root登陆帐户
    2、CentOS中修改yum源
    1、在CentOS上安装Java JDK的步骤
  • 原文地址:https://www.cnblogs.com/tsingke/p/10040758.html
Copyright © 2011-2022 走看看