《C++primer》第15章:面向对象程序设计

1、定义基类和派生类

定义基类

基类通常都定义一个虚析构函数

派生类经常(不总是)对基类的虚函数重新定义

当我们使用指针或引用调用虚函数时,该调用将被动态绑定

任何构造函数之外的非静态函数都可以是虚函数

关键字virtual只能出现在类内部的声明语句之前而不能用于类外部的定义

定义派生类

可将公有派生类对象绑定到基类的引用或指针上

派生类必须使用基类的构造函数来初始化它的基类部分

继承与静态成员

如果基类定义了一个静态成员,则在整个继承体系中只存在该成员的唯一定义

派生类的声明

声明中包含类名但不包含派生列表

被用作基类的类

如果想将某个类用作基类,则该类比较已经定义而非仅仅声明

防止继承的发生

在类名后加final

类型转换与继承

不存在从基类向派生类的隐式转换

在对象之间不存在类型转换

派生类向基类的自动类型转换只对引用或指针类型有效

当用一个派生类对象为一个基类对象初始化或赋值时,只有该派生类对象中的基类部分会被拷贝、移动和赋值,派生部分将被忽略

 

2、虚函数

必须为每一个虚函数都提供定义,不管它是否用到

派生类中的虚函数

派生类继承而来的虚函数的参数类型必须与基类一致,此外,返回类型也必须与基类一致,但有例外,当返回类型是类本身的指针或引用时,可不必一致

override说明符

override使用示例

虚函数与默认实参

传入派生类中的是基函数中的默认实参

派生类默认实参最好和基类默认实参一致

回避虚函数的机制

使用域作用符强迫虚函数执行某一特定版本

通常情况下,只有成员函数(或友元)中的代码才能使用域作用符

 

3、抽象基类

纯虚函数

书写 =0 就可将一个函数声明为纯虚函数,=0只能出现在类内部的虚函数声明语句处

可以为纯虚函数提供定义,但函数体必须在类的外部

含有纯虚函数的类是抽象基类

抽象基类不能创建对象

派生类构造函数只初始化它的直接基类

 

4、访问控制与继承

protected

protected成员对于类的用户来说是不可访问的,对于派生类的成员和友元是可访问的

派生类的成员或友元只能通过派生类对象来访问基类的受保护成员,派生类对于一个基类对象中的protected成员没有访问权限,不然的话我们只需要定义一个新类就可以绕开基类的protected访问保护了

public、private和protected继承

派生访问说明符对派生类的成员(和友元)能否访问其直接基类的成员没说明影响,对基类成员的访问权限只与基类中的访问说明符有关

若继承是public的,则派生类所有来自基类的成员都遵循原有访问权限

若继承是protected的,则派生类所有来自基类的成员都遵循原有访问权限,但最高为protected

若继承是private的,则派生类所有来自基类的成员都是private

派生类向基类转换的可访问性

友元与继承

友元关系不能继承,基类友元访问派生类无特殊性,派生类访问基类友元也无特殊性

改变个别成员的可访问性

通过using声明可改变成员的可访问性

派生类只能为那些它可以访问的名字提供using声明

默认的继承保护级别

使用class定义派生类默认private继承

使用struct定义派生类默认public继承

为了让继承关系清晰明了,最好将继承关系显示表现出来

 

5、继承中类的作用域

当存在继承关系时,派生类的作用域嵌套在基类的作用域中,如果一个名字在派生类中无法解析,编译器会继续在外层的基类中寻找定义

在编译时进行名字查找

名字冲突与继承

派生类可以重新定义在基类中的名字,重新定义的成员将隐藏在其基类中同名的成员

若想使用基类中的同名成员,可通过作用域运算符来使用

除了覆盖继承而来的虚函数外,派生类最好不要重新定义基类中出现的名字

名字查找先于类型检查

定义在派生类中的函数不会重载基类中的成员

即使参数列表不一致,基类中同名的函数仍然会被隐藏掉,因为编译器一旦找到名字,就不会继续找了

虚函数与作用域

基于上面规律,就可以理解为什么派生类中的虚函数的参数列表必须和基类一样了,如果不一样,则基类中的虚函数将被隐藏,起不到重载的作用了

通过基类调用隐藏的虚函数

覆盖重载函数

有时派生类仅需覆盖重载集合中的部分函数,但基于上面的规律,基类中的其它函数将被隐藏,这样我们就不得不为那些我们不想覆盖的函数重写,这样操作很繁琐

解决办法就是用using声明,这样就无需覆盖基类中的每一个函数版本了

 

6、构造函数与拷贝控制

虚析构函数

基类的析构函数一般定义为虚函数,目的是动态绑定使得引用或指针可以调用到具体的析构版本

如果析构函数不是虚函数,那么delete一个指向派生类对象的基类指针将产生未定义的行为

虚析构函数将阻止合成移动操作mark

mark mark mark

 

7、容器与继承

当派生类对象被赋值给基类对象时,派生类部分将被去掉,因此容器和存在继承关系的类型无法兼容

怎么解决上面的问题?

在容器中存放智能指针而非对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值