继承
继承是面向对象程序设计使用的代码复用的手段,可以在保持原有类的特性的基础上进行扩展,增加新的类。

class Person
{public:void Print(){cout << "name: " << name << endl;cout << "age: " << age;}
protected:string name = "xiaoming";int age = 18;
};
class Student :public Person
{public:void Print(){cout << name<<" ";cout << age<<" ";cout << _Id;}
protected:int _Id = 0001;
};


先看上面的代码,有两个类,Student类中没有定义name与int成员变量,为什么在Print函数当中,可以输出值呢?

我们把上面这种定义称为,Student类继承Person类,其中Person称为父类(基类),Student称为子类(派生类)。上面的代码可以给出一个简单的解释,儿子可以使用其父亲的一些东西。

继承的定义

继承包括:子类(派生类),继承方式,父类(基类)
父类中有些东西,不想被继承,所以可以通过给变其继承方式来改变。
继承方式:

但不同的继承方式,也会产生不同的变换。
说明:

  • 父类(基类)中的私有成员变量同样被继承到子类(派生类)中,但是对于子类而言,继承父类的私有成员,不论是在子类的类体外还是在类体内,都不能访问。
  • 父类的成员(变量、函数)如果不想在类外被访问,但需要在子类中被访问,可以将其成员的访问限定符定义为protected。
  • class默认的访问限定符为private,struct默认的访问限定符为public。
  • 在实际中一般都是用public的继承方式。

继承底层数据模型

赋值兼容规则

  • 当继承的方式为public时
    子类对象可以直接赋值给父类对象、父类的指针、父类的引用。
 Person p;Student s;p = s;Person *pp = &s;Person &p = s;


父类指针可以通过强制类型转换赋值给子类的指针。

Person *pp;
Student *ss = (Student*)pp;

继承的作用域—产生同名覆盖问题

  • 在继承体系中,子类与父类都有自己独立的作用域。
  • 子类和父类有同名的成员,子类将屏蔽父类对同名函数的直接访问,这就产生了同名隐藏,也称为重定义。如果想访问父类的成员函数可以使用:类名::基类成员
  • 只要子类成员名与父类成员名相同时,就构成重名覆盖。
class Person
{public:void Print(){cout << "name: " << name << endl;cout << "age: " << age;}
protected:string name = "xiaoming";int age = 18;
};
class Student :public Person
{public:void Print(){cout << name<<" ";cout << age<<" ";cout << _Id;Person::Print(); //调用父类中的成员函数}protected:int _Id = 0001;
};

派生类的默认成员函数

  • 子类(派生类)的构造函数必须调用父类的构造函数初始化父类的一成员,如果父类没有默认的构造函数,必须在子类中显示调用父类的构造函数
  • 子类(派生类)的拷贝构造函数必须父类的拷贝构造函数,完成子类的完全初始化。
  • 子类的operator=必须调用父类的operator=完成基类的复制
  • 子类的析构函数首先调用完自己的析构函数后,会主动调用父类的析构函数。(先清理子类部分再清理父类)
  • 子类构造先调用父类的构造,在调用自己的构造
class Person
{public:Person(const char* name = "xiaoming"):_name(name){cout << "Person()" << endl;}Person(const Person& s):_name(s._name){cout << "Person(const Person&)" << endl;}Person& operator = (const Person& s){if (this != &s){_name = s._name;}cout << "Person operator " << endl;return *this;}~Person(){cout << "~Person" << endl;}
protected:string _name; // 姓名
};class Student :public Person
{public:Student(const char* name, int _age):Person(),age(_age){  cout << "Student()" << endl;}Student(const Student& s):Person(s),age(s.age){cout << "Student(const Student&)" << endl;}Student& operator = (const Student& s){if (this != &s){cout << "Student operator = " << endl;}return *this;}~Student(){cout << "~Student()" << endl;}
private:int age;
};

继承与友元
友元关系不能被继承。基类的友元函数,不能访问子类的成员。例如:父亲的朋友,不是你的朋友。

继承与静态成员
基类定义了一个static成员,则整个继承体系中只有一个静态成员。

class Person
{public:Person()  //每次调用Person时,count++{++_count;}static int _count;
};
int Person::_count;class Student :public Person
{protected:int _num;
};class Graduate:public Student
{protected:string _seminarCourse;
};

菱形继承—钻石继承

单继承:一个子类只有一个父类
多继承:一个子类有多个父类
菱形继承是多类型的一种:B继承A,就对A的数据保存一份,C继承A,就对A的数据保存一份,当D多继承B,C就会对A的数据保存两份,所以会造成数据冗余与二义性。

解决方式:菱形虚拟继承。(详见下面链接)
https://blog.csdn.net/qq_42708024/article/details/104318891

C++---继承总结相关推荐

  1. 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题

    继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...

  2. kotlin中继承父属性使用构造方法

    kotlin中继承父属性使用构造方法 1. 定义父类,给它两个属性: abstract class AbstractResponseMessage {private var success = tru ...

  3. C++ 笔记(31)— 类继承

    1. 私有和保护 成员函数或成员数据可以是公有或者私有的.如果是公有的,那么它们可以被直接访问:如果是私有的,那么它们无法被直接访问.同时,还有一个 protected 保留字,在没有使用继承的时候, ...

  4. 使virtualenv从您的全局站点包继承特定的包

    / 猿问 使virtualenv从您的全局站点包继承特定的包 Python Bootstrap 冉冉说 2019-08-24 15:01:46 使virtualenv从您的全局站点包继承特定的包 我正 ...

  5. Django 模板继承4.2

    模板继承 模板继承可以减少页面内容的重复定义,实现页面内容的重用 典型应用:网站的头部.尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义 block标签:在父模板中预留区域,在子模板中填 ...

  6. C++ 继承与多继承

    继承的作用: 用已有的数据类型创建新的数据类型,并保留已有数据类型的特点,被继承的类成为父类或者基类,继承的类成为子类或者派生类. 继承的一般形式 class 子类 : [继承方法] 父类{ }; & ...

  7. python学习day24 继承 派生

    继承 class A(object):pass # 父类,基类,超类 object是类祖宗,一般默认不写 class B:pass # 父类,基类,超类 class A_son(A,B):pass # ...

  8. Go 学习笔记(36)— 基于Go方法的面向对象(封装、继承、多态)

    Go 面向对象编程的三大特性:封装.继承和多态. 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不 ...

  9. Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝

    1. 类继承 如下代码 class A(object):def show(self):print 'This is calss A'class B(A):def show(self):print 'T ...

  10. python基础——继承与派生、组合

    python基础--继承与派生 1 什么是继承: 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类成为基类或超累,新建的类成为派生类或子类 1.1 继承分为:单 ...

最新文章

  1. 继承和多态 3.0 -- 菱形继承
  2. 机器学习的优化目标、期望最大化(Expectation-Maximum, EM)算法、期望最大化(EM)和梯度下降对比
  3. pythonjson数据解析错误是什么意思_Python中的JSON解析错误
  4. 黑盒测试和白盒测试_黑盒测试综合策略
  5. linkerd mysql_linkerd ab部署测试
  6. 为什么python不能输入中文_一条命令解决mac版本python IDLE不能输入中文问题
  7. @j1 bootstrap
  8. 每天一点正则表达式复习(二)
  9. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_13使用骨架创建maven的web工程...
  10. 模糊提取器(Fuzzy Extractor)
  11. (转)PQ分区魔术师中文版分区教程
  12. HNOI 2018 滚粗记
  13. spring boot毕业生跟踪调查管理系统 毕业设计源码论文+答辩PPT
  14. EasyExcel锁定指定单元格 禁止表格复制
  15. 浅谈小微企业智能化财务转型
  16. Box2D和Chipmunk的一些对比
  17. Android自定义view--SurfaceView实现墨迹天气的风车效果
  18. C语言中全局变量和局部变量,内部函数和外部函数的区别
  19. 宿舍管理系统 住宿管理系统 寝室管理系统源码 java项目jsp web项目
  20. 文本转语音工具-Balabolka

热门文章

  1. 谈谈CountDownLatch和CyclicBarrier
  2. android实战开发02
  3. javascript的规范
  4. Linux下mysql源码包安装
  5. php把路由放在数据库,PHP导入Excel到数据库的方法 PHP把数据库数据导出到方法
  6. RTOS原理与实现06:计数信号量实现
  7. windows下批处理常用句法
  8. float 最小误差_关于float与double结果的误差
  9. 用bbp公式计算pi_家用配电箱里设计几个回路合适?用这个公式,计算起来很方便...
  10. mysql jsp分页技术_一个非常简单的分页技术MYSQL JSP 利用了mysql的LIMIT参数