C++:继承与派生


设计新类时可继承已有的类,这个已有的类被称为 基类或父类
• 基类是为解决以前的老问题而设计的,在面对新问题时其功能可能会显得不够完善。程序员
需要在继承的基础上对基类进行派生,例如添加新功能,或者对从基类继承来的功能进行某
些修改。派生的目的是为了解决新问题
• 通过继承与派生所得到的新类被称为 派生类或子类
• 继承与派生的编程原理是:程序员在定义新类的时候,首先继承基类的数据成员和函数成员;在此基础上进行派生,为派生类添加新成员,或对从基类继承来的成员进行重新定义或修改其访问权限在继承与派生的过程中,继承实现了基类代码的重用,派生则实现了基类代码的进化
• 派生类中的成员可分为2种:一是从基类继承来的成员,称为派生类中的 基类成员,二是定义时新增的成员,称为派生类中的 新增成员
C++语法: 定义派生类
class 派生类名 : 继承方式1 基类1, 继承方式2 基类2, ...... // 派生类声明部分
{
public :
新增公有成员
protected :
新增保护成员
private :
新增私有成员
} ;
各新增函数成员的完整定义 // 派生类实现部分
语法说明:
 定义派生类时,在派生类名的后面添加继承列表,在声明部分的大括号里声明新增成员,在实现部分编写各新增函数成员的完整定义代码;
 继承列表指定派生类从哪些基类继承。派生类可以只从一个基类继承( 单继承),也可以从多个基类继承( 多继
承)。每个基类以“ 继承方式 基类名”的形式声明,多个基类之间用“ ,”隔开;
 派生类将继承基类中除构造函数、析构函数之外的所有数据成员和函数成员。基类的构造函数和析构函数不能被继承,派生类需重新编写自己的构造函数、析构函数。
 继承后,派生类会对其基类成员按照继承方式进行再次封装。继承方式有3种: public(公有继承)、 protected(保护继承)和private(私有继承);
 public( 公有继承):派生类对其基类成员不做任何封装,它们在派生类中的访问权限与原来在基类中的权限相同;
 private( 私有继承):派生类对其基类成员做全封装,它们在派生类中的访问权限统统被改为private(私有权限),不管它们原来在基类中的权限是什么。使用私有继承,实际上是派生类要将其基类成员全部隐藏起来;
 protected( 保护继承):派生类对其基类成员做半封装。基类中的public成员被继承到派生类后,其访问权限被降
格成protected(保护权限)。基类中的protected、 private成员被继承到派生类后,其访问权限保持不变;
 在类声明部分的大括号中声明新增的数据成员、函数成员,并指定各新增成员的访问权限。在类实现部分编写各新增函数成员的完整定义代码。

同名覆盖:派生类中定义与基类成员重名的新增成员, 新增成员将覆盖基类成员。通过成员名访问时,所访问到的将是新增成员,这就是新增成员对基类成员的同名覆盖。同名覆盖后,被覆盖的基类成员仍然存在,只是被隐藏了。可以访问被覆盖的基类成员,其访问形式是: 基类名 :: 基类成员名

保护权限和保护继承
类的保护权限是向其派生类定向开放的一种权限
派生类的保护继承是向其下级派生类定向开放的一种半封装
程序员甲:定义类A( 类头文件A.h) 
class A // 定义类A
{
public:
A( int p1 = 0, int p2 = 0, int p3 = 0 ) // 构造函数
{ x = p1; y = p2; z = p3; }
int x; // 公有权限
private: int y; // 私有权限
protected: int z; // 保护权限
} ;
// 类A没有函数成员, 所以不需要类实现部分
 
程序员乙:使用类A定义对象( 1.cpp)程序员丙:使用类A定义派生类B( B.h)
#include <iostream>
using namespace std;
#include “A.h” // 声明类A
int main( )
{
A obj( 10, 20, 30 );
cout << obj.x << endl; // 正确: public
cout << obj.y << endl; // 错误: private
cout << obj.z << endl; // 错误: protected
return 0;
}
#include <iostream>
using namespace std;
#include “A.h” // 声明基类A
class B : public A
{
public:
void funB( ) // 新增成员访问基类成员
{
cout << x << endl; // 正确: public
cout << y << endl; // 错误: private
cout << z << endl; // 正确: protected
}
} ;
派生类对象的构造与析构
– 派生类的构造函数
派生类构造函数名( 形参列表 ) : 基类名 1( 形参1 ), 基类名 2( 形参2 ), ......
{
...... // 在函数体中初始化新增成员
} –
派生类对象中各数据成员的初始化顺序是:先调用基类构造函数,初始化基类成员;再执行派生类构造函数的函数体,初始化新增成员
– 如果派生类继承了多个基类,那么各基类成员的初始化顺序由其在派生类继承列表中的声明顺序决定,声明在前的基类成员先初始化(派生类的构造函数并不能直接初始化基类成员,因为基类成员可能是私有权限,所以必须调用基类的构造函数初始化基类成员,即初始化参数列表)
派生类的析构函数
– 派生类对象中数据成员的析构顺序是:先执行派生类析构函数的函数体,清理新增成员;再调用基类析构函数,清理基类成员。简单地说,对象的析构顺序与构造顺序反,即先析构新增成员,再析构基类成员
• 组合派生类的构造与析构
– 从基类继承来的成员(基类成员),二是新增的对象成员,三是新增的非对象成员
– 组合派生类的构造函数需依次初始化基类成员、新增对象成员、新增非对象成员。其中,初始化基类成员和新增对象成员需通过初始化列表,初始化新增的非对象成员则是在函数体中直接赋值。
语法细节:初始化基类成员时使用类名初始化。
– 组合派生类对象中各成员的析构顺序与其构造顺序相反,即先析构新增的非对象成员,再析构新增对象成员,最后才析构基类成员
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值