C++赋值兼容原则

时间:2022-12-15 20:55:58

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

C++赋值兼容原则的更多相关文章

  1. C++赋值兼容原则理解

    –赋值兼容原则(派生类对象是基类对象,反之不成立)–基类指针强制转换成派生类指针–派生类中重定义基类成员(同名覆盖) 假设, 一个基类 "普通人", 一个派生类 "超人& ...

  2. C++虚函数、赋值兼容原则

    #include <iostream.h> class A { public: void f1() { cout << "a" << endl; ...

  3. C&plus;&plus;语言笔记系列之十六——赋值兼容规则&amp&semi;amp&semi;多继承的二义性

    1.赋值兼容规则 (1)派生类对象能够给基类对象赋值,这样的情况下派生类对象将从基类继承的成员的值赋值给一个基类对象:可是不同意将一个基类的对象赋值给一个派生类. (2)能够将派生类对象的地址赋给基类 ...

  4. C&plus;&plus;:基类与派生类对象之间的赋值兼容关系

    4.5 基类与派生类对象之间的赋值兼容关系 在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量. 在赋值之前,先把整型数据转换为双精度型数据,然后再把它双精度型变量. ...

  5. 类型兼容原则(C&plus;&plus;)

    类型兼容原则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代. 通过公有继承,派生类得到了基类中除构造函数.析构函数之外的所有成员.这样,公有派生类实际具备了基类的所有功能,凡是基类能解 ...

  6. C&plus;&plus;中的继承详解(3)作用域与重定义,赋值兼容规则

    作用域与同名隐藏 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A" ...

  7. C&plus;&plus;中的继承(3)作用域与重定义,赋值兼容规则

    作用域与重定义(同名隐藏) 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A& ...

  8. C&plus;&plus;中的继承&lpar;3&rpar;作用域与重定义,赋值兼容规则

    1.作用域与重定义(同名隐藏) 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << " ...

  9. C&plus;&plus;:同名隐藏和赋值兼容规则

    一.同名隐藏 同名隐藏,即在C++的继承中,只要子类的函数名和父类的函数名相同,子类中的函数将会隐藏所有父类中和子类的成员函数同名的函数 特别注意: 和函数之间的重载不同,这里只要求函数的名字相同,而 ...

随机推荐

  1. 屏幕监视专家 v1&period;0 定时录制屏幕动画发送到指定邮箱

    ScreenWatcher v1.0功能:定时录制屏幕动画发送到指定邮箱,录制的动画为gif,可指定录制多长时间.指定几点直接开始录制,完全后台运行.作者:Bluefish 下载链接: http:// ...

  2. Flash Socket简单调试工具

    写了一个简单的Flash Socket调试工具,可用来简单调试本地或者外部socket服务器,使用的时候注意Flash socket的安全策略问题,有问题请联系sky-wang@qq.com.

  3. mongodb的安装及注意事项

    环境:win8 32bit 1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb ...

  4. java 解析XML文档

    Java 解析XML文档 一.解析XML文档方式: 1.DOM方式:将整个XML文档读取到内存中,按照XML文件的树状结构图进行解析. 2.SAX方式:基于事件的解析,只需要加载XML中的部分数据,优 ...

  5. code forces 148D Bag of mice (概率DP)

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  6. 手写事件代理函数 (Delegated function)

    ‘手写 ’ 这个词 ,面试是不是听过无数遍呢 ! 今天我们来手写一个这样的事件委托函数 => function( parent, selector, type ,  handle)  {} 你需 ...

  7. java&period;lang&period;Exception&colon; No tests found matching &lbrack;&lbrace;ExactMatcher&colon;fDisplayName&equals;fun2&rsqb;&comma; &lbrace;ExactMatcher&colon;fDisplayName&equals;fun2&lpar;cn&period;itcast&period;demo2&period;fun1&rpar;&rsqb;&comma; &lbrace;LeadingIdentifierMatcher&colon;fClassName&equals;cn&period;itcast&period;demo2&period;fun1&comma;fLeadi

    Junit报的错误, 在测试方法前面没有添加注解@Test

  8. 使用 Trace 将日志输入到文件中

    工具没有好坏,只有适不适用.由于项目中用 Log4Net 过重,所以使用 Trace 代替了 Log4Net 输入一些简单的日志信息: 自定义监听文件 using System; using Syst ...

  9. 2017 清北济南考前刷题Day 6 afternoon

    期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...

  10. GUC-8 小练习

    import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...