类的继承与派生
C++继承机制
C++继承机制
继承
继承是类与类之间的一种关系
定义:“类B继承类A”,或者说“类A派生类B”
类B中除了自己定义的成员之外,还自动包括了类A中定义的数据成员与成员函数,这些自动继承下来的成员称为类B的继承成员。
一、继承的语法
1、class 派生类名: 基类类名表{
public: 公有成员说明列表;
protected: 受保护成员说明列表;
private: 私有成员说明列表;
};
其中基类类名表的格式为:
access 基类类名1, ……, access 基类类名n
access为继承访问控制符,规定了派生类对基类的继承方式,可为public,private或者protected,继承访问控制符可省略,此时认为为private
在protected后定义的是保护段,其中的数据成员或成员函数称为受保护成员:具有公有成员与私有成员的双重角色。
2、一个类的受保护成员,对于其子孙类(派生类)的成员函数来说是公有的,对类本身及后代类之外定义的其他函数则是私有成员。
3、派生类可以重新定义基类的成员函数,覆盖基类的同名函数
4.通过类名限定符在派生类中使用基类的同名成员
二、继承访问控制规则
公有继承(公有派生)、私有继承、保护
继承访问控制 基类成员访问控制 在派生类中的访问控制
public public public
protected protected
private 不可访问
protected public protected protected protected
private 不可访问
private public private
protected private
private 不可访问
一、 派生类对象的存储组织
派生类的对象不仅存放了在派生类中定义的非静态数据成员,而且也存放了从基类中继承下来的非静态数据成员。
二、 类型兼容性
派生产品举例子
派生产品举例子
派生和继承的概念来自于人们认识客观世界的过程。
举个简单的例子:“狗”和“黑狗”。
当人们谈论“狗”的时候,知道它是哺乳动物。
有4条腿、1条尾巴,喜欢吃骨头......
若谈论“黑狗”,人们会怎么说呢?当然可以说:“黑狗也是哺乳动物,也有4条腿、1条尾巴,喜欢啃骨头......,并且它的毛是黑色的”。
但人们一般不这么说,而是说:“黑狗就是毛是黑色的狗/黑毛狗”。
显然后边这种说法,更简练。且它反映了“狗”和“黑狗”这两个概念之间的内在联系。“狗”和“黑狗”之间存在一条重要的联系,那就是所有的“黑狗”都是“狗”,或者说,“黑狗”是一类特殊的“狗”。
根据这个说法,“狗”所具有的特征(例如:4条腿、1条尾巴等),“黑狗”自然也具有。
也就是说:“黑狗”从“狗”那里继承了“狗”的全部特征。
用C++语言来描述上述问题,显然我们可以定义一个描述“狗”的类dog,但是如何定义描述“黑狗”的类blackDog呢?C++提供了一种机制,使得人们可以像“黑狗就是毛是黑色的狗/黑毛狗”那样定义一个新类blackDog。这种机制下,类blackDog自动拥有类dog的所有成员。 首先,“黑狗就是毛是黑色的狗/黑毛狗”是从一般的dog类通过特殊化而得到类blackDog的。这种通过特殊化已有的类来建立新类的过程,叫做“类的派生”,原有的类叫做“基类”,新建立的类则叫做“派生类”。
另一方面,从类的成员的角度来看,派生类自动地将基类地所有成员作为自己的成员,这叫做“继承”。基类和派生类又可以分别叫做“父类”和“子类”,有时也成为“一般类”和“特殊类”。
类的派生和继承是面向对象程序设计方法和C++语言最重要的特征之一。
因为客观世界本身是有层次的,在人们认识客观世界的过程中,由一般到特殊的演绎思维发挥着巨大作用。演绎的过程在绝大多数情况下表现为层次分类的过程。
继承使得程序员可以在一个较一般的类的基础上很快地建立一个新类,而不必从零开始设计每个类。
idea看类继承关系
idea看类继承关系
在面向对象编程中,类继承关系是指一个类(称为子类或派生类)可以继承另一个类(称为父类或基类)的属性和方法。这种继承关系可以帮助我们组织和重用代码,提高代码的可维护性和可扩展性。
首先,让我们来看一下继承关系的基本概念。在一个继承关系中,子类继承了父类的属性和方法,这意味着子类可以访问并使用父类中的属性和方法。这样的设计可以减少重复的代码,提高代码的复用性。同时,子类还可以通过添加新的属性和方法来扩展父类的功能,从而实现定制化的需求。
另外,继承关系还可以帮助我们实现多态。多态是面向对象编程中一个重要的概念,它指的是不同的子类对象可以对同一个方法做出不同的响应。这种灵活性可以让我们写出更加通用和灵活的代码。
此外,继承关系还可以通过抽象类和接口来实现。抽象类是不能被实例化的类,它的存在是为了让其他类继承它并实现它的抽象方法。接口则是一种特殊的抽象类,它只包含抽象方法和常量,而没有属性和具体方法。通过抽象类和接口,我们可以定义规范和约束,从而实现更加灵活和可扩展的设计。
总之,类继承关系是面向对象编程中非常重要的概念,它可以帮助我们组织和重用代码,实现多态和灵活的设计。通过合理地使用继承关系,我们可以写出更加清晰、简洁和易于维护的代码。
派生类
继承与派生类
1 知识要点
1. 掌握继承和派生的定义,派生类的定义方法。
(1) 掌握继承的两种类型:单继承和多继承。
(2) 掌握private,public,protected三种继承方式的特点。继承方式决定了基类中的成员在派生类中的属性。三种继承方式的共同点:基类的private成员在派生类中不可见。区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3) 掌握派生类中的构造函数和析构函数的使用。基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4) 掌握派生类的同名覆盖规则。
(5) 掌握赋值兼容规则。基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2. 掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3. 掌握虚基类的概念和定义方法。在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
2 典型例题分析与解答
例题1:下列对派生类的描述中,( )是错误的。
A. 一个派生类可以作为另一个派生类的基类
C++中类继承public,protected和private关键字作用详解及派生类的访问权限
C++中类继承public,protected和private关键字作⽤详解及派⽣
类的访问权限
注意:本⽂有时候会⽤Visual Studio Code⾥插件的⾃动补全功能来展⽰访问权限的范围(当且仅当⾃动补全范围等价于对象访问权限范围
的时候),但是不代表⽇常使⽤时只要是出现在⾃动补全范围内的可调⽤对象/成员都是可访问的。
⼀,公有继承
#include
#include
#include
#include
#include
class Base{
public:
int PublicBase;
void PublicPrint() {std::cout << "PublicPrint()" << std::endl;}
protected:
int ProtectedBase;
void ProtectedPrint() {std::cout << "ProtectedPrint()" << std::endl;}
private:
int PrivateBase;
void PrivatePrint() {std::cout << "PrivatePrint()" << std::endl;}
};
class Derived : public Base{
public:
void DerivedPrint() {
std::cout << "DerivedPrint()" << std::endl;
std::cout << ProtectedBase << std::endl;
//若要访问protected的数据成员需要通过派⽣类⾥的成员函数访问
PublicPrint();
ProtectedPrint();
}
};
int main(void)
{
Derived der;
der.PublicPrint();
der.PublicBase;
//der.ProtectedBase; //不能直接访问protected数据成员
类的继承举例 -回复
类的继承举例 -回复
标题:类的继承举例详解
在面向对象编程中,类的继承是一个非常重要的概念。它允许我们创建一个新的类,该类继承了现有类的属性和方法,从而减少代码重复,提高代码的复用性和灵活性。以下我们将通过一个具体的例子,逐步解析类的继承及其应用。
首先,我们需要理解什么是基类和派生类。基类,也称为父类或超类,是被继承的类。派生类,也称为子类,是从基类继承的类。派生类可以有自己的属性和方法,也可以重写或扩展基类的属性和方法。
假设我们正在开发一个动物模拟系统,我们首先定义一个基类“Animal”。
python
class Animal:
def __init__(self, name, age):
= name
self.age = age
def speak(self):
pass
在这个“Animal”类中,我们定义了一个初始化方法`__init__`,用于设置动物的名字和年龄。我们也定义了一个`speak`方法,但目前它只是一个空方法,因为不同的动物会有不同的叫声。
接下来,我们可以创建两个派生类“Dog”和“Cat”,它们都从“Animal”类继承。
python
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
在“Dog”和“Cat”类中,我们都重写了`speak`方法,使其返回特定的叫声。这是因为虽然所有的动物都有`speak`行为,但是每种动物的叫声都是独特的。
现在我们可以创建“Dog”和“Cat”的实例,并调用它们的方法。
python
my_dog = Dog("Rex", 5)
print(my_) # 输出: Rex
继承与派生:派生类对基类成员的访问控制之保护继承与私有继承(转)
继承与派⽣:派⽣类对基类成员的访问控制之保护继承与私有继
承(转)
鸡啄⽶在编程⼊门系列上⼀节中讲了,这⼀节接着讲剩下的两种继承⽅式:保护继承和私有继承。
⼀.保护继承
在保护继承⽅式中,基类的公有成员和保护成员被派⽣类继承后变成派⽣类的保护成员,⽽基类的私有成员在派⽣类中不能访问。因为
基类的公有成员和保护成员在派⽣类中都成了保护成员,所以派⽣类的新增成员可以直接访问基类的公有成员和保护成员,⽽派⽣类的对象
不能访问它们,上⼀讲鸡啄⽶说过,类的对象也是处于类外的,不能访问类的保护成员。对基类的私有成员,派⽣类的新增成员函数和派⽣
类对象都不能访问。
通过上述保护继承的讲解,相信⼤家对类的有 更加深刻的理解了。假设A类是基类,B类是从A类继承的派⽣类,A类中有保护成员,则
对派⽣类B来说,A类中的保护成员和公有成员的访问权限是⼀样的。⽽ 对A类的对象的使⽤者来说,A类中的保护成员和私有成员都⼀样不
能访问。可见类中的保护成员可以被派⽣类访问,但是不能被类的外部对象(包括该类的对象、 ⼀般函数、其他类等)访问。我们可以利⽤
保护成员的这个特性,在软件开发中充分考虑数据隐藏和共享的结合,很好的实现代码的复⽤性和扩展性。
鸡啄⽶举个简单的例⼦讨论下保护成员的访问属性。
class Base
{
protected:
int x; // 基类的保护成员
};
int main()
{
Base base;
base.x = 0; // 编译报错
return 0;
}
这段代码在编译的时候会报错,错误就出在通过对象base访问保护成员x时,就像上⾯讲的,对Base类的对象base的使⽤者来说,Base
类中的保 护成员x和私有成员的访问特性是⼀样的,所以对象base不能访问x,这样跟使⽤私有成员⼀样通过保护成员实现了数据的隐藏。
class Base
{
protected:
int x; // 基类的保护成员
};
class Child : public Base
c++继承与派生习题答案
1.概念填空题
1。1在C++中,三种派生方式的说明符号为 public 、 private 、 protected不加说明,则默认的派生方式为private 。
1。2当公有派生时,基类的公有成员成为派生类的 公有成员 ;保护成员成为派生类的 保护成员 ;私有成员成为派生类的 不能直接访问成员
。当保护派生时,基类的公有成员成为派生类的 保护成员;保护成员成为派生类的 保护成员 ;私有成员成为派生类的 不能直接访问成员 .
1.3 派生类的构造函数一般有3项工作要完成:首先 基类初始化 ,其次 成员对象初始化,最后 执行派生类构造函数体 .
1.4多继承时,多个基类中的同名的成员在派生类中由于标识符不唯一而出现 二义性 。在派生类中采用 虚基类 或 作用域分辨符 来消除该问题.
2.简答题
2.1 派生类如何实现对基类私有成员的访问?
2。2什么是类型兼容规则?
2.3派生类的构造函数是怎样的执行顺序,析构函数的执行顺序是如何实现的?
2.4继承与组合之间的区别与联系是什么?
2.5什么是虚基类?它有什么作用?含有虚基类的派生类的构造函数有什么要求,什么是最远派生类,建立一个含有虚基类的派生类的对象时,为什么由最远派生类的构造函数负责虚基类的初始化?
3.选择题
3.1下面对派生类的描述中,错误的是(D ).
A.一个派生类可以作为另外一个派生类的基类
B.派生类至少有一个基类
C.派生类的成员除了它自己的成员外,还包含了它的基类的成员
D.派生类中继承的基类成员的访问权限到派生类中保持不变
3.2下列对友元关系叙述正确的是(A)。
A.不能继承
B.是类与类的关系
C.是一个类的成员函数与另一个类的关系
D.提高程序的运行效率
3。3当保护继承时,基类的(B)在派生类中成为保护成员,不能通过派生类的对象来直接访问。
C++(面向对象的程序设计)考前必背的名词解释和简答题
1
C++(面向对象的程序设计)考前必背的名词解释和简答题
1. 封装 封装是将数据和代码捆绑到一起,避免了外界的干扰和不确定性。例如 C++中的 类,它定义了该集合中每个对象所共有的属性和方法。
2. 继承 继承是让某个类型的对象获得另一个类型的对象的特征。例如:C++中子类对父 类的继承,子类具有父类的特性,同时还可以拥有自己的新特性。
3. 多态 多态是指不同类型的对象接收相同的消息时产生不同的行为。 多态机制使具有不 同内部结构的对象可以共享相同的外部接口,通过这种方式减小代码的复杂度。 例如函数的重载。
4. 什么是 this 指针?为什么要用 this 指针?
this 指针是类中的一个特殊指针,当类实例化时,this 指针指向对象自己;而 在类的声明时,指向类本身。通过它不仅可以提升成员函数操作的效率,而且能 简化运算符重载代码。
5. 叙述公有、私有、保护成员在类中、类外和对象中的访问权限。 类中的关键字 public, private, protected 声明了类中的成员与类外之间的关 系,称为访问权限 。 对于 public 成员来说,他们是公有的,可以在类外和对象中访问。 对于 private 成员来说,他们是私有的,不能在类外和对象中访问,数据成员只 能由类中的函数使用,成员函数只允许在类中调用。 对于 protected 成员来说,他们是受保护的,具有半公开性质,可以在类中与子 类中访问。
6. 构造函数和析构函数的作用是什么?
构造函数的功能是在创建对象时,给数据成员赋初值,即给对象初始化。 析构函数的功能是释放一个对象,在对象删除前,用来做一些内存释放等清理工 作。
7. 什么是类的继承和派生?
继承是指一个事物可以继承其父辈全部或部分的特性, 同时本身还有自己的特性。 当一个新类从一个已定义的类中派生后,新类不仅继承了原有类的属性和方法, 并且还拥有自己新的属性和方法,称为类的继承和派生。
继承与派生
实验4 继承与派生
班 级 学号(最后两位) 姓 名 成 绩
一、实验目的
1. 熟练掌握类的继承,能够定义和使用类的继承关系
2. 掌握派生类的声明与实现方法
3. 掌握类构造函数的初始化列表与作用域分辨率的使用方法
4. 理解虚基类在解决二义性问题中的作用.
二、实验内容
1.定义一个基类有姓名、性别、年龄,再由基类派生出教师类和学生类,教师类增加工号、职称和工资,学生类增加学号、班级、专业和入学成绩。
2.声明一个哺乳动物Mammal类,再由此派生出狗Dog类,声明一个Dog类的对象,观察基类与派生类的构造函数与析构函数的调用顺序。
3.定义一个Point类,派生出矩形类Rectangle和圆类Circle,计算各派生类对象的面积Area()。
4.设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生的,要求输出一个圆桌的高度、面积和颜色等数据。
5.定义一个大学生类student,函数私有数据成员:姓名、学号、校名,并为它定义带参数的构造函数,参数带缺省值的构造函数和输出数据成员值的print()公有成员函数,另定义研究生类,它以公有继承方式派生于类student,新增加“研究方向、导师名”两个私有数据成员,并定义带参数的构造函数和输出研究生数据的print()公有成员函数。在main()函数中定义基类和派生类对象,对类进行测试。
三、实验源程序、测试与结论
1.
#include
#include
using namespace std;
class person
{
public:
person(string name_,char sex_,int age_):name(name_),sex(sex_),age(age_){}
void show()
{
cout<<"name: "<
cout<<"sex: "<
