IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 《Effective C++》学习笔记(条款36:绝不重新定义继承而来的non-virtual函数) -> 正文阅读

[C++知识库]《Effective C++》学习笔记(条款36:绝不重新定义继承而来的non-virtual函数)

最近开始看《Effective C++》,为了方便以后回顾,特意做了笔记。若本人对书中的知识点理解有误的话,望请指正!!!

如果在基类中有一个 public 函数 mf,创建一个派生类对象 x ,然后创建一个基类指针指向 x 调用这个函数,创建一个派生类指针指向 x 调用这个函数,两者调用的函数相同,那么结果应该是一样的吗?
一般来说会是一样的,但如果 mf 是个普通函数且派生类重新定义 mf 函数,将会遮掩基类的相应函数,通过派生类调用该函数,永远是派生类的版本,而非基类的版本。

class B {
public:
    void mf();
    ...
};
class D : public B  {
public:
    void mf();    // 遮掩了基类B的mf函数(可详见条款33)
    ...
};

D x;
B* pB = &x;
D* pD = &x;
pB->mf();    // 调用 B::mf
pD->mf();    // 调用 D::mf

造成这样现象的原因是,普通l函数如 B::mfD::mf 都是静态绑定(statically bound,见条款37)。意思是由于 pB 的类型是 B*,通过 pB 调用的普通函数永远是 B 所定义的版本,即使 pB 指向一个类型为 B 派生出来的类对象。
但虚函数就是动态绑定(dynamically bound,见条款37),所以,它们不会出现这个问题。如果 mf 是个虚函数,不论是通过 pBpD 调用 mf ,都会导致调用 D::mf ,因为 pBpD 真正指向的都是一个类型为 D 的对象。

如果你设计了 D 类并重新定义从基类 B 继承来的普通函数 mf,当 D 对象调用 mf 函数都可能表现出 B 或 D 的行为。决定因素不再对象自身,而在于“指向该对象的指针”当初的声明类型。引用造成的结果和指针差不多。

在之前的条款32中说过,public 继承 意味着 is-a 关系。条款34中也描述了为什么在 class 内声明一个 普通函数 会为该 class 建立起一个不变性,凌驾其特殊性。如果这两个观点放在 B 类 和 D 类以及 普通成员函数 B::mf 身上,那么:

  • 适用于 B 对象的每一件事,也适用于 D 对象,因为每个 D 对象都是一个 B 对象
  • B 类的派生类一定会继承 mf 的接口和实现,因为 mf 是 B 的一个 普通函数

如果 D 重新定义 mf ,你的设计就出现矛盾了,如果 D 真有必要实现出与 B 不同的 mf ,那么 D 继承 B 干嘛?如果 D 必须继承自 B,且 D 的 mf 与 B 的 mf 不同,那么就应该将 mf 声明为虚函数,而不是普通函数。

从中可得出一个结论:任何情况下都不该重新定义一个继承而来的 普通函数

条款37:绝不重新定义继承而来的默认参数值

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-15 15:39:53  更:2021-11-15 15:41:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:07:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码