继承---派生类(C++)

1.继承不是代码复用唯一方式,类之间除了继承外,还有部分与整体的关系,即聚集关系,如飞机与发动机类,从纯代码复用角度讲,聚集比继承好,避免了继承与封装的矛盾,对于聚集,一个类只有一个接口,即类的实例用户接口(public),而对于继承,除了实例用户接口还有派生类接口(public和protected)

 

2.派生类对基类的默认继承方式为private,C++中,对派生类有以下规定
a.派生类除了可以拥有基类所以成员(基类构造函数和赋值操作符重载函数除外)外,可以有新成员
b.派生类可以给出新成员,也可对基类的成员重定义
c.对于基类某个成员,如果派生类中没有,该成员在派生类中可见,如果有,需要使用基类名受限访问
d.定义派生类时需要见到基类定义
e.基类友元不是派生类友元,基类是另一个类友元,派生类不是该类友元
f.派生类不能直接访问基类私有成员,必须要通过基类的非私有成员函数访问基类私有成员

 

3.在面向对象程序中,派生类往往可以看成是基类的子类型:发给基类对象的消息也能发给派生类对象以及基类对象标识可以标识派生类对象

 

4.构造与析构:如果一个类既有基类又有成员对象类,则在创建该类对象时,该类构造函数先调用基类构造函数,再调用成员对象类构造函数,最后执行自己函数体,析构时,按相反顺序执行。默认是调用基类默认构造函数,如果需调用基类的非默认构造函数,则必须在派生类构造函数的成员初始化表中指出。对于拷贝构造函数,派生类的隐式拷贝构造函数(由编译程序提供)将会调用基类的拷贝构造函数,而派生类自定义的拷贝构造函数默认情况下不会调用基类的拷贝构造函数,可在派生类自定义拷贝构造函数的初始化表中显式指出调用基类拷贝构造函数。派生类不从基类继承赋值操作,如果派生类没有提供赋值操作符重载,系统会提供隐式赋值操作符重载函数,对基类成员调用基类赋值操作符重载进行赋值,对派生类成员逐个赋值。对于派生类对象,如果系统提供的隐士赋值操作不能满足要求,在派生类中重载赋值操作符=,并显式调用基类的赋值操作符来实现基类成员的赋值

 

5.多态性:多态是为了实现接口重用,允许将父对象设为一个或更多的子对象相等的技术,赋值之后,父对象可以根据当前赋值给它的子对象的特性以不同方式运作,多态是面向对象核心概念。
a.对象类型多态:派生类对象的类型可以是派生类,也可是基类
b.消息的多态:公共消息集中的消息可以发送到基类对象,也可发送到派生类对象
c.对象标识的多态:基类指针或引用可以指向基类对象,也可指向或引用派生类对象
class A
{
 int x,y;
public:
 void f();
};
class B:public A
{
 int z;
public:
 void f();
 void g();
};
fun1(A &a)
{
 a.f
}
fun2(A *pa)
{
 pa->f();
}
A a;
fun1(a);
fun2(&a);
B b;
fun1(b);
fun2(&b);
对于fun1和fun2中a.f(),pa->f(),调用是A中的f还是B中的f,解决方案有两个:
(1)采用静态绑定:在编译时,根据a,pa的静态类型决定f属于哪个类,由于a,pa静态类型为A类的,所以f为A::f
(2)采用动态绑定:在运行时,根据a,pa实际引用的对象类型(动态类型)来确定f属于哪个类
C++是注重程序效率的语言,由于采用动态绑定的程序效率不高,C++默认采用静态绑定方式,对于上面问题,C++按方案(1)解决,如果需要动态绑定,必须在程序中显式指出
可将A中的f声明为虚函数
class A
{
public:
 virtual void f();
}
这样会在运行时根据a,pa实际引用的对象类型确定f属于哪个类,一旦基类中某个成员函数为虚函数,不管派生类中是否给出virtual声明,派生类(以及派生类的派生类、以此类推)中对其重定义的成员函数均为虚函数。重定义指:对派生类中定义的成员函数,其函数名、参数个数、类型以及返回类型与基类的某个虚函数相同。当基类的虚成员函数返回类型为某个类C或其指针或引用时,派生类中重定义的成员函数的返回类型也可以是C的public的派生类或其指针或引用。派生类对基类虚函数的重定义称为超越或覆盖(override)。
虚函数的几点限制:
(1)只有类的成员函数才可以是虚函数
(2)静态成员函数不能是虚函数
(3)构造函数不能是虚函数
(4)析构函数可以(往往)是虚函数
基类构造函数中对虚函数的调用不采用动态绑定,因为创建派生类对象时,基类构造函数先于派生类构造函数体执行,否则会造成对未初始化的数据进行操作。只有通过引用或指针来访问对象的虚函数时才进行动态绑定。如果通过引用或指针访问对象的非虚函数和不通过引用或指针来访问对象的成员函数,则不采用动态绑定。而是采用静态绑定。另外,通过类名首先来访问虚函数时也不采用动态绑定。利用虚函数机制,可以通过基类的指针或引用来访问派生类中对基类重定义的成员函数。有时,需要通过基类的指针或引用访问派生类中新定义的成员函数,这时,需要采用强制类型转换把基类指针或引用转换成派生类指针或引用。但这种转换有时是不安全的,导致对不属于基类对象的内存空间值的修改,可采用C++的另一种类型转换操作来实现基类到派生类的转换:
A *p=new A;
B *q;
q=dynamic_cast<B *>(p);
if(q!=NULL)
{
}
dynamic_cast类型转换时,根据p实际指向的对象类型来判断转换的合法性。如果合法,进行转换并返回转换后的对象地址;否则,返回NULL,上面的q将会得到NULL,从而不会调用B类的成员函数g

 

6.纯虚函数:只给出函数声明而没给出实现的虚成员函数,在函数原型后加=0;包含纯虚函数的类称为抽象类,抽象类不能创建对象,抽象类作用在于为派生类提供一个基本框架和一个公共的对外接口。派生类应对抽象基类的纯虚成员函数进行实现

 

7.析构函数作为虚函数时必要的:当将派生类对象地址赋予基类对象指针时,如果析构函数不是虚函数,且派生类构造函数分配了堆内存,则该基类指针撤销时调用基类析构而不会调用派生类析构,从而造成对内存泄露,将析构设为虚函数,保证先调用派生类析构再调用基类析构,从而避免内存泄露
构造函数不能作为虚函数:虚函数机制允许调用一个只知道接口而不知道准确对象类型的函数,但如果创建一个对象,必须要知道对象的准确类型,构造函数不能为虚函数

 

8.类中若有虚函数(包括从基类继承来的),编译程序会为其创建一个虚函数表,表中记录该类中所有虚函数入口地址。当创建一个包含虚函数的类对象时,在所创建对象的内存空间中有一个隐藏的指针指向该对象所属类的虚函数表

 

9.单个参数的构造函数如果不添加explicit关键字,会定义一个隐含的类型转换(从参数的类型转换为自己),添加explicit关键字会消除这种隐含转换,同样也能阻止”以赋值语法进行带有转型操作的初始化“

 

10.重载:编写一个与已有函数同名但参数表不同的函数,重载不是面向对象的编程,只是一种语法规则,与多态没有直接关系
覆盖:派生类重写基类的虚函数,重写的函数与基类虚函数有一致的参数表和返回值

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++中的类继承派生是面向对象编程中的重要概念。在C++中,可以使用公有继承、保护继承和私有继承来实现类的继承派生。 公有继承是最常见的一种继承方式,它可以使得基类的公有成员派生类中仍然是公有的,保护成员派生类中变为保护的,私有成员派生类中不可访问。\[1\] 保护继承是一种特殊的继承方式,它可以使得基类的公有和保护成员派生类中变为保护的,私有成员派生类中不可访问。\[2\] 私有继承是一种特殊的继承方式,它可以使得基类的公有和保护成员派生类中变为私有的,私有成员派生类中不可访问。私有继承主要用于实现"实现继承",即派生类通过继承基类的实现来实现自己的功能。\[3\] 在派生类中,可以使用基类成员函数和成员变量,但是访问权限受到继承方式的限制。公有继承和保护继承可以访问基类成员函数和成员变量,私有继承只能在派生类内部访问基类成员函数和成员变量。 总结起来,C++中的类继承派生可以通过公有继承、保护继承和私有继承来实现,不同的继承方式决定了派生类基类成员访问权限。 #### 引用[.reference_title] - *1* *2* [C++ 面向对象 - 类的继承派生](https://blog.csdn.net/m0_62598965/article/details/124610795)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C++面向对象-继承派生](https://blog.csdn.net/D23333A/article/details/116640148)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值