C++基类和派生类
- 格式:pdf
- 大小:72.93 KB
- 文档页数:6
C++派⽣类与基类对象赋值情况⼀、普通赋值 (同名隐藏)
⼦类对象调⽤和⽗类相同的函数名,该⽗类的函数名会被隐藏,只会调⽤⼦类的函数。
Class A
{
public:
void show();
void show(int);
}
Class B : public A
{
public :
void show();
void printf();
}
int main()
{
B b;
b.show();
a.show(); //这时候⼦类已经隐藏⽗类的⽅法,⽗类不能在调⽤⾃⼰的函数
a.show(0) //同上
}
⽗类的引⽤或指针被⼦类对象的对象或地址赋值后,它会调⽤⽗类⾃⼰相应的⽅法
⼆、⼦类对象地址给⽗类指针赋值
通过⼦类的对象的地址给⽗类的指针赋值----->⽗类指针只能调⽤⼦类中从⽗类继承的函数或者变量
int main()
{
A * a ;
B b;
a = &b;
a->show();
a->printf(); //这个是错误的调⽤,不能调⽤⼦类的函数⽅法
}
三、⼦类对象给⽗类的引⽤赋值
⽗类的引⽤只能访问由⼦类继承⽗类的函数或者变量
int main()
{
A &a;
B b;
a = b;
a.show();
a.list(); //这个引⽤是错误的 }。
C++作业答案第7章继承7.1 选择题1.在c++中,类与类之间的继承关系具有( c )。
(a) 自反性 (b) 对称性 (c) 传递性 (d) 反对称性2.下列关于类的继承描述中,( a,b )是错误的。
(a) 派生类可以访问基类的所有数据成员,调用基类的所有成员函数(b) 派生类也是基类,所以基类具有派生类的全部属性和方法(c) 继承描述类的层次关系,派生类可以具有与基类相同的属性和方法(d) 一个基类可以有多个派生类,一个派生类可以有多个基类3.当一个派生类公有继承一个基类时,基类中的所有公有成员成为派生类的( a )。
(a) public 成员 (b)private成员(c) protected成员 (d)友员4.当一个派生类私有继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( b )。
(a) public 成员 (b)private成员(c) protected成员 (d)友员5.当一个派生类保护继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( c )。
(a) public 成员 (b)private成员(c) protected成员 (d)友员6.不论派生类以何种方式继承基类,都不能使用基类的( b )。
(a) public 成员 (b)private成员(c) protected成员 (d)public 成员和protected成员7.下面描述中,错误的是( b, c )。
(a) 在基类定义的public成员在公有继承的派生类中可见,也能在类外被访问(b) 在基类定义的public和protected成员在私有继承的派生类中可见,在类外可以被访问(c) 在基类定义的public和protected成员在保护继承的派生类中不可见(d) 在派生类中不可见的成员要变成可访问的需进行访问声明8.在c++中,不能被派生类继承的函数是( b,c )。
(a) 成员函数 (b)构造函数(c) 析构函数 (d)静态成员函数9.在创建派生类对象时,构造函数的执行顺序是( d )。
C++基类和派⽣类整理⾃ 通过继承机制,可以利⽤已有的数据类型来定义新的数据类型。
所定义的新的数据类型不仅拥有新定义的成员,⽽且还同时拥有旧的成员。
我们称已存在的⽤来派⽣新类的类为基类,⼜称为⽗类。
由已存在的类派⽣出的新类称为派⽣类,⼜称为⼦类。
在++中,⼀个派⽣类可以从⼀个基类派⽣,也可以从多个基类派⽣。
从⼀个基类派⽣的继承称为单继承;从多个基类派⽣的继承称为多继承。
派⽣类的定义格式 单继承的定义格式如下: class <派⽣类名>:<继承⽅式><基类名> { <派⽣类新定义成员> }; 其中,<派⽣类名>是新定义的⼀个类的名字,它是从<基类名>中派⽣的,并且按指定的<继承⽅式>派⽣的。
<继承⽅式>常使⽤如下三种关键字给予表⽰: public 表⽰公有基类; private 表⽰私有基类; protected 表⽰保护基类; 多继承的定义格式如下: class <派⽣类名>:<继承⽅式1><基类名1>,<继承⽅式2><基类名2>,… { <派⽣类新定义成员> }; 可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于⼀个。
派⽣类的三种继承⽅式 公有继承(public)、私有继承(private)、保护继承(protected)是常⽤的三种继承⽅式。
1. 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派⽣类的成员时,它们都保持原有的状态,⽽基类的私有成员仍然是私有的。
2. 私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派⽣类的私有成员,并且不能被这个派⽣类的⼦类所访问。
3. 保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为派⽣类的保护成员,并且只能被它的派⽣类成员函数或友元访问,基类的私有成员仍然是私有的。
C++中三种继承⽅式的区别还可参考另⼀篇⽂章:public公有继承protected保护继承private我们知道类的private和protected成员,在类外是不可以使⽤的.只有public成员可以在类外直接使⽤.公有继承时,基类的private成员派⽣类也不可⽤,基类的public和protected成员在派⽣类中可直接使⽤.继承过来(变成派⽣类相应的public和protected成员)只有public成员在派⽣类外可以直7a64e58685e5aeb931333262363034接使⽤.保护继承时,基类的private成员仍为有私有.基类的public和protected成员变成派⽣类的protected成员,这时在派⽣类外也不能直接使⽤原基类的public成员时,基类的private成员仍为有私有.基类的public和protected成员将变成派⽣类的private成员.举个例⼦.class A{public:int m_nTelNum;protected:int m_nAge;private:int m_nMoney;};class B:public A{void SetTelNum(int nTelNum){m_nTelNum=nTelNum;}void SetAge(int nAge){m_nAge=nAge;}void SetMoney(int nMoney){m_nMoney=nMoney;//这⾥就出现错误,因为基类的private成员不能⽤.};B objB;//创建B类的对象objBobjB.m_nTelNum=123456;//可以objB.m_nAge=30;//错误.public继承中基类的protected在派⽣类中是protectedobjB.m_nMoney=100;//更错误,在派⽣类中都不可以直接使⽤.在类外就更不能了.class C:protected A{void SetTelNum(int nTelNum){m_nTelNum=nTelNum;}void SetAge(int nAge){m_nAge=nAge;}void SetMoney(int nMoney){m_nMoney=nMoney;//这⾥就出现错误,因为这是基类的private成员不能⽤.}};C objC;//创建C类的对象objCobjC.m_nTelNum=123456;//注意这⾥和public的区别,这⾥错误,m_nTelNum变成了C类的protected成员objC.m_nAge=30;//错误.protected继承中基类的protected在派⽣类中是protected,这与public同相objC.m_nMoney=100;//更错误,在派⽣类中都不可以直接使⽤.在类外就更不能了.class D:private A{void SetTelNum(int nTelNum){m_nTelNum=nTelNum;}void SetAge(int nAge){m_nAge=nAge;void SetMoney(int nMoney){m_nMoney=nMoney;//这⾥就出现错误,因为这是基类的private成员不能⽤.}};D objD;//创建D类的对象objDobjD.m_nTelNum=123456;//错误,m_nTelNum变成了D类的private成员objD.m_nAge=30;//错误.private继承中基类的protected在派⽣类中是privateobjD.m_nMoney=100;//更错误,在派⽣类中都不可以直接使⽤.在类外就更不能了.从例⼦来看,三种继承从派⽣类内部引⽤来看好像没有区别,只在类外引⽤时表现不同.现在还看不出public和protected继承的区别那再看⼀个例⼦.class E:public B{void SetTelNum(int nTelNum){m_nTelNum=nTelNum;//可以因为这是B的公有成员}void SetAge(int nAge){m_nAge=nAge;//可以因为这是B的保护成员,现成变成E的protected成员}void SetMoney(int nMoney){m_nMoney=nMoney;//这个肯定不可以!}};E objE;//objE.m_nTelNum=123456;//可以//其它的两个就不能⽤了.class F:public C{void SetTelNum(int nTelNum)m_nTelNum=nTelNum;//可以因为这是C的保护成员,这⾥与public继承已经有区别但还没有表现出来 }void SetAge(int nAge){m_nAge=nAge;//可以因为这是C的保护成员,现成变成E的protected成员}void SetMoney(int nMoney){m_nMoney=nMoney;//这个肯定不可以!}};F objF;objF.m_nTel=123456;//错误,因为这是F的保护成员.注意与E类区别class G:public D{void SetTelNum(int nTelNum){m_nTelNum=nTelNum;//不可以因为这是D的private成员,注意这⾥区别}void SetAge(int nAge){m_nAge=nAge;//不可以因为这是D的private成员,注意区别}void SetMoney(int nMoney){m_nMoney=nMoney;//这个肯定不可以!}};//那G在类外就没有了可以引⽤的继承过来成员了!//这些继承⽅式是很难理解的.最好的办法就是多写代码去试.。
5.2 基类和派生类在C++中,当一个类被其他类继承时,被继承的类称为基类(base class)。
继承其他类特性的类称为派生类(derived class)。
从本质上看,基类是具有一个类集合中的公共特性,派生类在继承基类特性的同时可以加入自己独有的特性。
基类与派生类之间反映出下述三种不同的现象:(1)派生类是基类的具体化。
即模拟概念层次,表示“is-a”的关系。
(2)派生类是基类的延迟定义。
可以定义一个抽象基类,定义一些操作,使它们服从一定的协议,但许多可能并未实现,然后定义非抽象的派类,实现抽象基类中定义的行为。
这时派生类不是基类的具体化,而是抽象类的实现。
在JA V A中,有专门的纯虚类,称为接口,其作用就是为不同的类提供一个统一的接口,同时间接实现多继承(JA V A不支持多继承)。
(3)派生类是基类的结合。
当一个派生类有多于一个的基类时,它们组合在一起形成具有所有基类行为的类型。
这时要注意,不要用继承表达聚合关系。
5.2.1 基类与派生类的说明先看一个例子。
[例5.1] 派生类的说明EX5_1.CPP。
继承基类的派生类定义的一般形式:class derived_class_name:access_specifier base_class_name{……};其中access_specifier可以是3个关键字之一:public、private(默认值)或protected。
派生类也称为子类、导出类。
它具有下述特点:(1)可在基类所提供有基础上包含新成员;(2)可在自己类中隐藏基类的任何成员;(3)为新类重新定义基类中的函数;[例5.2] 子类的特点EX5_2.CPP。
5.2.2 派生类的继承权与访问域派生类的继承权如果不能有效在加以限制,就不能按照实际情况表达求解问题的复杂性。
因此访问权限是一个很重要的问题。
(1)对于基类的私有成员,派生类及派生类的使用者无权访问。
(2)对于基类的公有成员,则按派生类的定义,分为三种情况:①私有派生,继承基类的公有成员作为自己的私有成员,这些成员只能被派生类的成员函数访问。
《基类和派生类的构造顺序》同学们,今天咱们来聊聊基类和派生类的构造顺序,这可是编程里很重要的知识哟!想象一下,基类就像是一个基础的房子框架,派生类呢,就是在这个基础框架上进行装饰和扩展的部分。
当我们创建一个派生类的对象时,先构造的是基类。
为啥呢?因为基类是基础呀,得先把基础打好。
比如说,基类里可能有一些最基本的设置,像房子的地基。
举个例子,假如基类是“动物”,派生类是“猫”。
在创建一只猫的时候,得先有动物的一些基本特征,比如有生命、能活动,然后才有猫的独特特点,像会抓老鼠、爱撒娇。
所以呀,记住这个顺序,先基类后派生类,这样我们在编程的时候就能更清楚啦!《基类和派生类的构造顺序》同学们,咱们来深入了解一下基类和派生类的构造顺序。
先把基类想象成一个大蛋糕的底层,派生类就是在这个底层上面加的各种美味装饰。
当我们要做出一个完整的蛋糕,也就是创建一个派生类对象时,肯定要先有底层的蛋糕坯,这就是基类的构造。
比如说,基类是“交通工具”,派生类是“汽车”。
那得先有交通工具的通用属性,像能移动,然后才有汽车的特别之处,比如有四个轮子、靠汽油驱动。
这个构造顺序很重要哦,如果顺序不对,就像做蛋糕先放装饰再做底层,那可就乱套啦!《基类和派生类的构造顺序》同学们,今天讲讲基类和派生类的构造顺序,这个可有意思啦!把基类当成是一棵大树的树干,派生类就是树干上长出来的树枝和树叶。
当这棵树要长大的时候,肯定得先有树干呀,这就是基类的构造。
比如基类是“水果”,派生类是“苹果”。
先要有水果的共性,像能吃、有营养,然后才有苹果的特点,比如红红的、甜甜的。
要是顺序反了,就像树先长叶子再长树干,那多奇怪呀!所以一定要记住,先构造基类,再构造派生类哟!。
本讲讨论基类和派生类的基本概念。
通过继承机制,可以利用已有的数据类型来定义新的数据类型。
所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。
我们称已存在的用来派生新类的类为基类,又称为父类。
由已存在的类派生出的新类称为派生类,又称为子类。
在C++(C++培训)++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。
从一个基类派生的继承称为单继承;从
多个基类派生的继承称为多继承。
派生类的定义格式
单继承的定义格式如下:
class <派生类名>:<继承方式><基类名>
{
<派生类新定义成员>
};
其中,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。
<继承方式>常使用如
下三种关键字给予表示:
public 表示公有基类;
private 表示私有基类;
protected 表示保护基类;
多继承的定义格式如下:
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基
类名2>,…
{
<派生类新定义成员>
};
可见,多继承与单继承的区别从定义格式上看,主要是多继承的
基类多于一个。
派生类的三种继承方式
公有继承(public)、私有继承(private)、保护继承(protected)是常
用的三种继承方式。
1. 公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的。
2. 私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
3. 保护继承(protected)
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的
私有成员仍然是私有的。
下面列出三种不同的继承方式的基类特性和派生类特性。
不同继承方式的基类和派生类特性
继承方式基类特性派生类特性公有继承
public
public protected
private protected 不可访问私有继承
public
private protected
private
private 不可访问保护继承
public protected protected
private
protected
不可访问
为了进一步理解三种不同的继承方式在其成员的可见性方面的区别,下面从三种不同角度进行讨论。
对于公有继承方式:
(1) 基类成员对其对象的可见性:
公有成员可见,其他不可见。
这里保护成员同于私有成员。
(2) 基类成员对派生类的可见性:
公有成员和保护成员可见,而私有成员不可见。
这里保护成员同
于公有成员。
(3) 基类成员对派生类对象的可见性:
公有成员可见,其他成员不可见。
所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。
这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是
不同的。
对于私有继承方式:
(1) 基类成员对其对象的可见性:
公有成员可见,其他成员不可见。
(2) 基类成员对派生类的可见性:
公有成员和保护成员是可见的,而私有成员是不可见的。
(3) 基类成员对派生类对象的可见性:
所有成员都是不可见的。
所以,在私有继承时,基类的成员只能由直接派生类访问,而无
法再往下继承。
对于保护继承方式:
这种继承方式与私有继承方式的情况相同。
两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。
上述所说的可见性也就是可访问性。
关于可访问性还有另的一种说法。
这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。
一般规则如下:
公有继承时,水平访问和垂直访问对基类中的公有成员不受限
制;
私有继承时,水平访问和垂直访问对基类中的公有成员也不能
访问;
保护继承时,对于垂直访问同于公有继承,对于水平访问同于
私有继承。
对于基类中的私有成员,只能被基类中的成员函数和友元函数所
访问,不能被其他的函数访问。
基类与派生类的关系
任何一个类都可以派生出一个新类,派生类也可以再派生出新类,因此,基类和派生类是相对而言的。
基类与派生类之间的关系可以有如下几种描述:
1. 派生类是基类的具体化
类的层次通常反映了客观世界中某种真实的模型。
在这种情况下,不难看出:基类是对若干个派生类的抽象,而派生类是基类的具体化。
基类抽取了它的派生类的公共特征,而派生类通过增加行为将
抽象类变为某种有用的类型。
2. 派生类是基类定义的延续
先定义一个抽象基类,该基类中有些操作并未实现。
然后定义非抽象的派生类,实现抽象基类中定义的操作。
例如,虚函数就属此类情况。
这时,派生类是抽象的基类的实现,即可看成是基类定义的延续。
这也是派生类的一种常用方法。
3. 派生类是基类的组合
在多继承时,一个派生类有多于一个的基类,这时派生类将是
所有基类行为的组合。
派生类将其本身与基类区别开来的方法是添加数据成员和成员函数。
因此,继承的机制将使得在创建新类时,只需说明新类与已有类的区别,从而大量原有的程序代码都可以复用,所以有人称类是“可
复用的软件构件”。