C++学习笔记44:继承与派生

类的组合,类的继承

类的组合(汽车类,轮子类,此时可以把轮子类组合到汽车类;)

类的继承(交通工具类,汽车类,此时汽车类可以派生自交通工具类;)

组合:常用描述has a..

继承:常用描述is a ..

如果既可以用组合又可以用派生解决,那首选组合方式;

继承与派生的目的  
  继承的目的:实现设计和代码的重用

  派生的目的:当新的问题出现,原有程序无法解决,需要对原有的程序进行改造

派生类的构成

  吸收基类的成员

  改造基类的成员

  添加新的成员

吸收基类的成员

  默认情况下派生类包含了全部的基类中除了构造函数和析构函数之外的所有的成员

  C++11规定可以使用using语句继承基类的构造函数

改造基类成员

  如果派生类声明了一个和某基类成员同名的新成员,派生类的新成员就隐藏或者覆盖了外层同名的成员

公有继承:
派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问直接访问基类中的private成员;

通过派生类的对象:只能访问public的成员

私有继承(private):
继承的访问控制:
基类的public和protected成员:都以private身份出现在派生类中;
基类的private成员:不可以直接访问
访问权限:
派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的
private成员;
通过派生类的对象不能访问从基类中继承的任何成员;

保护继承(protected):
继承的访问控制:

基类的public和protected成员:都以protected身份出现在派生类中

基类的private成员:不可以直接访问

访问权限:
派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问基类中的private成员;

通过派生类的对象:不能直接访问从基类继承的任何成员;

protected成员的特点和作用

对建立其所在类对象的模块来说,它与private成员的性质相同

对于其派生类来说,它与public成员的性质相同

既实现了数据隐藏,又方便继承,实现代码的重用

class A {

protected:

  int x;
};

int main()

{

  A a;

  a.x = 5;//错误

}

类型转换

  • 公有派生类对象可以被当作基类的对象使用,反之则不行;
  • 派生类的对象可以隐含转换为基类的对象
  • 派生类的对象可以初始化基类的引用
  • 派生类的指针可以隐含转换为基类的指针
  • 通过基类对象名、指针只能使用从基类继承的成员

注意:不要重新定义继承而来的非虚函数

默认情况下:

基类的构造不被继承,派生类需要定义自己的构造函数;

C++11规定

可以使用using语句继承基类构造函数;

但是只能初始化从基类继承的成员;对于派生类新增的成员无法完成初始化;

语法形式:

using B::B;

若不继承基类的构造函数

派生类新增的成员:派生类定义构造函数完成初始化

继承来的成员:自动调用基类的构造函数初始化

派生类的构造函数需要给基类的构造函数传递参数;

单继承时构造函数的定义语法:

派生类名::派生类名(基类所需的形参,本类成员所需的形参):

基类名(参数表),本类成员初始化列表

{

//其他的初始化操作

}

派生类与基类的构造函数

当基类有默认的构造函数时

派生类构造函数可以不向基类的构造函数传递参数;

构造派生类的对象时,基类的默认构造函数将被调用;

如需要执行基类中带参数的构造函数,那么

派生类构造函数应该为基类构造函数提供参考;

多继承且有对象成员时派生的构造函数定义语法

派生类名::派生类名(形参表):

基类名1(参数),基类名2(参数),...基类名n(参数),

本类成员(含对象成员)初始化列表

{

//其他的初始化操作

}

注释:此处的本类成员指的是类的成员,当然也可以是本类包括的其他类的对象;

执行次序按照定义时候的顺序执行;

派生类的复制构造函数:
若派生类没有声明复制构造函数,则编译器会在需要时生成一个隐含的复制构造函数;

先调用基类的复制构造函数;

再为派生类新增的成员执行复制;

若派生类定义复制构造函数

一般都要为基类的复制构造函数传递参数,复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数;

基类的复制构造函数形式参数类型是基类对象的引用,实参可以是派生类对象的引用;

例如:

C::C(const C &c1):B(c1) {}

访问从基类中继承的成员时,

当派生类与基类中有相同的成员时:

1.若没有特别的限定,则通过派生类对象使用的是派生类中的同名成员;

2.如要通过派生类对象访问基类中被隐藏的同名成员,可以使用基类名和作用域操作符号::来限定;

二义性问题:
如果从不同的基类继承了同名的函数,但是在派生类中没有定义同名的成员,派生类对象名或引用名 .成员名,“派生类指针->成员名”访问存在二义性问题。

解决方式:用类名限定

当继承多个基类时(假如两个基类又继承自另一个相同的类,此时容易出现继承相同数据的情况),容易导致继承内容相同的情况,在操作过程中容易导致数据的冗余以及数据的不一致;

虚基类

问题:

  当派生类从多个基类派生,而这些基类有共同的基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性;

方案:

  声明虚基类

  以virtual说明基类继承方式

  例:class B1:virtual public B

作用:

  主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题;

  为最远的派生类提供唯一的基类成员,而不是重复产生多次复制;

注意:

  在第一级继承时就要将共同基类设计为虚基类;

虚基类以及其派生类的构造函数

建立对象时所指定的类称为最远派生类;

虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。

在整个继承结构中,直接或者间接继承虚基类的所有派生类,都必须在构造函数的成员初始化列表中为虚基类的构造函数列出参数。如果未列出,则表示调用该虚基类的默认构造函数;

在建立对象时,只有最远派生类的构造函数调用基类的构造函数,其他类对虚基类构造函数的调用被忽略。

目标:降低程序的复杂性,提高代码的可复用性。

http://www.xuetangx.com/courses/course-v1:TsinghuaX+00740043_2x_2015_T2+sp/courseware/8d1fd477f469492ba2c1297e6ace6f5d/2a889505dd584a639363f2b4e8726040/

时间: 2024-10-23 14:53:58

C++学习笔记44:继承与派生的相关文章

Java学习笔记之继承

一.继承的基础 在Java术语中,被继承的类叫超类(superclass),继承超类的类叫子类(subclass). 举例说明: 1 class Box 2 { 3 public double width; 4 public double height; 5 public double depth; 6 7 //重载构造方法 8 public Box(Box ob) 9 { 10 width = ob.width; 11 height = ob.height; 12 depth = ob.dep

C++学习笔记之继承

一.基类和派生类 很多时候,一个类的对象也“是”另一个类的对象,如矩形是四边形,在C++中,矩形类Rectangle可以由四边形类Quad继承而来,于是,四边形类Quad是基类,矩形类Rectangle是派生类.但是如果说四边形一定是矩形显然不对.几个简单的基类和派生类的例子: 基类                         派生类   食物 米饭.面条.水饺   交通工具 汽车.火车.飞机 国家 中国.美国.西班牙 可以看出,每个派生类的对象都是基类的一个对象,并且一个基类可以有很多派生

C++ Primer Plus学习笔记之继承类的初始化顺序

C++ Primer Plus学习笔记之继承类的初始化顺序 基类的构造函数,析构函数和操作符函数operator=是不能被派生类继承的: 那么,当创建一个派生类对象时,怎样调用基类的构造函数对基类的数据进行初始化呢??? 答案是:构造函数执行时遵行先兄长(基类),再客人(对象成员),后自己(派生类)的顺序: 另一方面,执行析构函数时,先执行派生类的析构函数,再执行基类的析构函数.原因是,对基类的破坏隐含了对派生类的破坏,所以派生类的析构函数必须先执行: #include<iostream> u

C++学习笔记13-类继承

1.  类模板的 static 成员[不同于C#中的static] 类模板可以像任意其他类一样声明static 成员.以下代码: template <classT> class Foo { public: static std::size_tcount() { return ctr; } // other interfacemembers private: static std::size_tctr; // otherimplementation members }; 定义了名为Foo 的类模

[原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

PHP学习笔记之继承(面向对象三大特性之一)

今天学习了面向对象的三大特性之一继承 继承:子类可以继承父类的一切 特点就是单继承: 制造一个父类 //继承:子类可以继承父类的一切//特点:单继承 //父类class Ren{ public $name; public $sex; public $yuyan; function Say() { echo $this->name."正在讲话!"; }} //美国人的子类class America extends Ren{ public $ziben; //子类对父类的方法重写 f

java学习笔记(六)继承

继承是面向对象编程中最重要的特征之一,它允许通过继承一个已经存在的类,来编写一个新类.已有的类称为父类,也可以称为基类,超类,新类称为子类也称为派生类. 继承使用关键字extends,用在类名之后,例:public void class salary extends Employee(){ } 子类salary 继承父类Employee java中的类只能继承一个类. 子类能继承父类中用public protected 修饰的成员. 继承的单根性(单继承):一个java类只能有一个父类. 继承的

OC学习笔记 面向对象 继承与组合

一.基本概念 程序的世界和人类的“对象”世界在思想上是没有设么区别的,富二代继承了父母,自然就拥有了父母拥有的所有资源,子类继承了父类同样就拥有了父类所有的方法和属性(成员变量). 在这里动物是猫类和狗类的父类,黑猫和白猫类是猫类的子类. 继承的好处: (1)抽取出了重复的代码 (2)建立了类和类之间的联系 继承的缺点: 耦合性太强 二.OC中的继承 @interface Animal:NSObject //动物里继承了NSObject,获得NSObject类的方法: @end @interfa

黑马程序员——JAVA学习笔记四(继承、接口、内部类)

1,    通过extends关键字让类与类之间产生继承关系.多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需定义这些属性和行为,只要继承那个类即可,已存在的类叫做超类,基类,或父类.新类称为子类,派生类,孩子类. 子类可以直接访问父类中的非私有的属性和行为.子类无法继承父类中私有的内容.JAVA不支持多继承,只支持单继承,多实现. 继承提高了代码复用性,让类与类之间产生了关系.为多态提供了前提. 2,    super关键字代表父类中成员变量内存空间的标示.两个作用