继承

struct Person {
int age;
int sex;
}; struct Teacher {
int age;
int sex;
int level;
int classId;
};

如上代码中可以看见,Teacher类与Person类都存在着相同的2个成员age和sex,那么这就相当于重复编写了,

我们可以通过继承的方式避免这样重复的编写(当前类名称:要继承的类名称):

Teacher类继承Person类

struct Teacher:Person {
int level;
int classId;
};

创建对象的对应反汇编代码如下,可以清晰的看见与我们正常的内存布局是一样的:



那么继承是什么?这就很好理解了,继承的本质就是数据复制,子类(派生类)继承(复制)父类(基类)的

数据,在这里Person父类(基类),Teacher为子类(派生类);继承可以减少重复代码的编写。

假设,子类中存在一个与父类中相同的成员会如何?

struct Person {
int age;
int sex;
}; struct Teacher:Person { // Inherit
int age;
int classId;
};

我们可以创建一个对象来看一下对应的宽度和反汇编代码:

void main() {
Teacher t;
t.age = 30;
t.sex = 1;
t.classId = 20;
printf("%d", sizeof(t));
printf("%d", sizeof(t));
return;
}

首先看下数据宽度,我们会发现是16,那也就是说这里不管如何你只要继承了,在编译器中两个成员还是会直接添加过来,Teacher的成员依然是4个「4成员*4数据宽度(int类型) = 16

再来看下反汇编代码:

之前我们已经看过了正常的内存布局了,在这里,很明显,少了一个0x10位置的成员,那么按照内存布局应该是这样的:

0x10 → Person.age

0x0C → Person.sex

0x08 → Teacher.age

0x04 → Teacher.classId

而在这里创建对象编译器使用的age成员默认就是当前类Teacher的成员;想要使用父类中的成员可以使用这种

方式(对象名.父类名称::成员名称):

void main() {
Teacher t;
t.Person::age = 30; // Father
t.age = 30;
t.sex = 1;
t.classId = 20;
return;
}

我们可以多次继承么,或者说继承仅仅局限于子、父关系么?如下代码,B继承了A,C继承了B,C是否只继承了B的v和n?

struct A {
int x;
int y;
}; struct B:A {
int v;
int n;
}; struct C:B {
int p;
int o;
};

我们可以来打印一下C的数据宽度:

结果是24,那么就说明C不仅仅继承了B,还继承了A;再换个说法就是,继承的本质是数据的复制,那也就是说当复制完(继承)后才是其本身,B的本身就是4个成员x、y、v、n。

除了这种方式以外,我们想实现同样的效果可以使用多重继承(当前类:继承的类A, 继承的类B):

struct A {
int x;
int y;
}; struct B {
int v;
int n;
}; struct C:A,B { // Multiple
int p;
int o;
};

但这种方式在很多面向对象语言中是不允许出现的,在C++中是可以使用的,其内存分布也与第一种方式不一样:

最后:继承的类A和继承的类B的顺序,谁在前,谁就在内存分布中的前面;不推荐使用多重继承,这会增加程序的复杂度。

C++(继承)的更多相关文章

  1. javaScript的原型继承与多态性

    1.prototype 我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉 ...

  2. JavaScript的继承实现方式

    1.使用call或apply方法,将父对象的构造函数绑定在子对象上 function A(){ this.name = 'json'; } function B(){ A.call(this); } ...

  3. javascript中的继承与深度拷贝

    前言 本篇适合前端新人,下面开始...... 对于前端新手来说(比如博主),每当对js的对象做操作时,都是一种痛苦,原因就是在于对象的赋值是引用的传递,并非值的传递,虽然看上去后者赋值给了前者,他们就 ...

  4. 谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  5. JS继承类相关试题

    题目一: //有关于原型继承的代码如下:function Person(name) {   this.name = name;}Person.prototype = {     getName : f ...

  6. JS继承之寄生类继承

    原型式继承 其原理就是借助原型,可以基于已有的对象创建新对象.节省了创建自定义类型这一步(虽然觉得这样没什么意义). 模型 function object(o){ function W(){ } W. ...

  7. JS继承之借用构造函数继承和组合继承

    根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...

  8. JS继承之原型继承

     许多OO语言都支持两种继承方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支 ...

  9. 深入浅出JavaScript之原型链&继承

    Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...

  10. 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型

    前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.

随机推荐

  1. 2023 年十大 API 管理趋势

    本文探讨了 API 管理在数字化转型中的重要性,以及 API 管理面临的挑战和发展机遇.文章重点介绍了十大 API 管理发展趋势,包括 API 安全性.API 标准化.云端 API 管理解决方案.低代 ...

  2. ROS机器人摄像头寻线

    ROS机器人摄像头寻线 连接小车 注意:必须在同一区域网 ssh clbrobort@clbrobort 激活树莓派主板 roslaunch clbrobot bringup.launch 开启摄像头 ...

  3. 吃透Redis面试八股文

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...

  4. Win Node.js安装教程

    前言: 一.下载 下载地址:https://registry.npmmirror.com/binary.html?path=node/ 二.安装(以下为傻瓜式安装操作)  三.验证安装 to be c ...

  5. Python-趣味小程序

    1.效果 2.代码 import sys import time def print_act(word): #print('\n'+' '+'\r') #让光标回到行首 sys.stdout.writ ...

  6. ABC294Ex K-Coloring

    Statement 对一张简单无向图进行 \(k\) 染色,满足对于每条边的两个端点颜色不同,求方案数. \(n,m\leq 30\). Solution 无向图 \(k\) 染色问题,很经典的问题. ...

  7. AGC061 F Perfect String

    毒瘤出题人,史诗加强 AGC 的 F-- 然而我连原题都不会,所以只学了原题做法. 翻译一下题意就是给定一张循环网格图,求经过 \((0,0)\) 的闭合回路条数. 由于网格图中每一个位置都等价,所以 ...

  8. Linux下七种文件类型、文件属性及其查看方法

    1.七种文件类型 普通文件类型 Linux中最多的一种文件类型, 包括 纯文本文件(ASCII):二进制文件(binary):数据格式的文件(data);各种压缩文件.第一个属性为 [-] 目录文件 ...

  9. 2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山

    2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度.比如, {3,1,2,4,5}.{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山.山峰A和山 ...

  10. 2021-11-04:计算右侧小于当前元素的个数。给你`一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右

    2021-11-04:计算右侧小于当前元素的个数.给你`一个整数数组 nums ,按要求返回一个新数组 counts .数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧 ...