Effective C++ 2e Item37

C++ 知识补充 向量(vector)是一个封装了动态大小数组的顺序容器(SequenceContainer)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。C++中map提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值。 阅读详情

条款37: 决不要重新定义继承而来的非虚函数

有两种方法来看待这个问题:理论的方法和实践的方法。让我们先从实践的方法开始。毕竟,理论家一般都很耐心。

假设类D公有继承于类B,并且类B中定义了一个公有成员函数mf。mf的参数和返回类型不重要,所以假设都为void。换句话说,我这么写:

class B {
public:
  void mf();
  ...
};

class D: public B { ... };

甚至对B,D或mf一无所知,也可以定义一个类型D的对象x,

D x;                          // x是类型D的一个对象

那么,如果发现这么做:

B *pB = &x;                   // 得到x的指针

pB->mf();                     // 通过指针调用mf

和下面这么做的执行行为不一样:

D *pD = &x;                   // 得到x的指针

pD->mf();                     // 通过指针调用mf

你一定就会感到很惊奇。

因为两种情况下调用的都是对象x的成员函数mf,因为两种情况下都是相同的函数和相同的对象,所以行为会相同,对吗?

对,会相同。但,也许不会相同。特别是,如果mf是非虚函数而D又定义了自己的mf版本,行为就不会相同:

class D: public B {
public:
  void mf();                  // 隐藏了B::mf; 参见条款50

  ...

};


pB->mf();                     // 调用B::mf

pD->mf();                     // 调用D::mf

行为的两面性产生的原因在于,象B::mf和D::mf这样的非虚函数是静态绑定的(参见条款38)。这意味着,因为pB被声明为指向B的指针类型,通过pB调用非虚函数时将总是调用那些定义在类B中的函数 ---- 即使pB指向的是从B派生的类的对象,如上例所示。

相反,虚函数是动态绑定的(再次参见条款38),因而不会产生这类问题。如果mf是虚函数,通过pB或pD调用mf时都将导致调用D::mf,因为pB和pD实际上指向的都是类型D的对象。

所以,结论是,如果写类D时重新定义了从类B继承而来的非虚函数mf,D的对象就可能表现出精神分裂症般的异常行为。也就是说,D的对象在mf被调用时,行为有可能象B,也有可能象D,决定因素和对象本身没有一点关系,而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。

实践方面的论据就说这么多。我知道你现在想知道的是,不能重新定义继承而来的非虚函数的理论依据是什么。我很高兴解答。

条款35解释了公有继承的含义是 "是一个",条款36说明了为什么 "在一个类中声明一个非虚函数实际上为这个类建立了一种特殊性上的不变性"。如果将这些分析套用到类B、类D和非虚成员函数B::mf,那么,

· 适用于B对象的一切也适用于D对象,因为每个D的对象 "是一个" B的对象。
· B的子类必须同时继承mf的接口和实现,因为mf在B中是非虚函数。

那么,如果D重新定义了mf,设计中就会产生矛盾。如果D真的需要实现和B不同的mf,而且每个B的对象 ---- 无论怎么特殊 ---- 也真的要使用B实现的mf,那么,每个D将不 "是一个" B。这种情况下,D不能从B公有继承。相反,如果D真的必须从B公有继承,而且D真的需要和B不同的mf的实现,那么,mf就没有为B反映出特殊性上的不变性。这种情况下,mf应该是虚函数。最后,如果每个D真的 "是一个" B,并且如果mf真的为B建立了特殊性上的不变性,那么,D实际上就不需要重新定义mf,也就决不能这样做。

不管采用上面的哪一种论据都可以得出这样的结论:任何条件下都要禁止重新定义继承而来的非虚函数。

QLoRA实战指南:单卡3090/4090高效微调大模型 QLoRA(Quantized Low-Rank Adaptation)是一种面向大语言模型的高效参数微调技术,其核心原理是将4-bit NF4量化与低秩矩阵增量更新协同耦合,在冻结主权重的前提下精准注入领域知识。相比全参数微调,它显著降低显存占用与计算开销,同时保持接近原模型的推理质量,已成为工业级LLM领域适配的事实标准。该技术特别适用于中文结构化任务(如合同解析、工单抽取、医疗术语标准化)及资源受限场景(单卡RTX 3090/4090),支持端到端落地——从数据清洗、LoRA模块配置、动态分桶训练,到 阅读详情

相关推荐

从理论到波形:NE555多谐振荡器设计与示波器实战验证

本文详细介绍了NE555多谐振荡器的设计原理与实战验证方法。从基础理论到电路参数计算,再到面包板搭建与示波器测量,全面解析如何利用NE555芯片实现稳定的方波输出。通过实际案例演示了频率调整、占空比优化等技巧,并提供了常见问题排查指南,帮助电子爱好者快速掌握这一经典电路设计。

weixin_29159613的博客 280

36:绝不重新定义继承而来的non-virtual函数

绝对不要重新定义继承而来的non-virtual函数。

cqxm11的博客 288

使用Docker搭建MaxKB智能体平台

【代码】使用Docker搭建MaxKB智能体平台。

janthinasnail的博客 708

Effective C++条款36:绝不重新定义继承而来的non-virtual函数(Never redefine an inherited non-virtual function)

Effective C++条款36:绝不重新定义继承而来的non-virtual函数(Never redefine an inherited non-virtual function)

CltCj的博客 632

syslog RFC5424协议详解

RFC5424协议解读与报文分析。

chenwr2018的博客 6690

DETRs with Collaborative Hybrid Assignments Training论文阅读与代码

在这篇论文中,作者观察到在DETR中将过少的 Query 分配为正样本,采用一对一的集合匹配,会导致对编码器输出的监督稀疏,严重损害编码器的区分特征学习,反之亦然,也会影响解码器中的注意力学习。为了缓解这个问题,作者提出了一种新颖的协同混合分配训练方案,名为Co-DETR,以从多样的标签分配方式中学习更高效、更有效的基于DETR的检测器。这种新的训练方案可以通过训练多个并行辅助 Head ,以一对多的标签分配方式(如ATSS和Faster RCNN)进行监督,轻松增强端到端检测器中编码器的学习能力。

qingjing0413的博客 1153

this指针

this是一个指针,它时时刻刻指向你这个实例本身。你可以看到它的成员函数、成员变量,this指针本质上是“成员函数”的形参。你可以看见桌子、椅子、地板等,静态成员函数中不能使用this指针。但是房子你是看不到全貌了。对于一个类的实例来说,当你进入一个房子后,不能给this指针赋值。

m0_63783532的博客 8503

交叉熵损失函数基本概念及公式

对于二分类问题,模型的输出通常是一个标量,表示样本属于正类的概率。因此,在二分类的交叉熵损失函数中,我们只需要考虑一个概率值,即模型预测为正类的概率。具体来说,当真实标签为1时,我们关注模型预测为正类的概率;当真实标签为0时,我们关注模型预测为负类的概率。因此,二分类的交叉熵损失函数可以表示为:其中,y 表示真实标签,取值为 0 或 1;p 表示模型预测为正类的概率。而对于多分类问题,模型的输出通常是一个向量,表示样本属于各个类别的概率。因此,在多分类的交叉熵损失函数中,我们需要考虑所有类别的概率。

qlkaicx的博客 1万+

条款36:绝不重新定义继承而来的非虚函数(Never redefine an inherited non-virtual function)

Effective C++ 之条款36

weixin_43739503的博客 190

飞牛fnNAS搭建个人小账本

本文介绍了如何在飞牛NAS上部署ezBookkeeping个人记账应用。该开源工具支持多平台使用,具备双因素认证、多级分类等功能。文章详细讲解了Docker激活、镜像下载、容器部署等步骤,并展示了账户管理、交易记录等基础操作。同时指导用户通过ZeroTier实现远程访问,方便随时随地使用个人记账系统。该方案既保障了数据隐私,又提供了专业记账功能,适合对财务隐私敏感的用户。

dgnankai的专栏 782

educoder实训——计算几何形状的表面积与体积

educoder python实训

qq_41234663的博客 1230

条款36:绝不重新定义继承而来的non-virtual函数

假设class D是由class B以public形式派生而来,class B定义有一个public成员函数mf,由于mf的参数和返回值都不重要,所以定义两者都为void。

依然爱猪的博客 641

详解YOLOv8网络结构/环境搭建/数据集获取/训练/推理/验证/导出/部署

YOLO(You Only Look Once)系列算法因其高效、准确等特点而备受瞩目。由2023年Ultralytics公司发布了YOLO的最新版本YOLOv8是结合前几代YOLO的基础上的一个融合改进版。本文YOLOv8网络结构/环境搭建/数据集获取/训练/推理/验证/导出/部署,从网络结构的讲解从模型的网络结构讲解到模型的部署都有详细介绍,同时在本专栏中还包括YOLOv8模型系列的改进包括个人提出的创新点,传统卷积、注意力机制、损失函数的修改教程,能够帮助你的论文获得创新点。

Snu77的博客 8万+

Effective C++ 2e Item38

  条款38: 决不要重新定义继承而来的缺省参数值让我们从一开始就把问题简化。缺省参数只能作为函数的一部分而存在;另外,只有两种函数可以继承:虚函数和非虚函数。因此,重定义缺省参数值的唯一方法是重定义一个继承而来的函数。然而,重定义继承而来的非虚函数是一种错误(参见条款37),所以,我们完全可以把讨论的范围缩小为 "继承一个有缺省参数值的虚函数" 的情况。既然如此,本条款的理由就变

lostmouse的专栏 1145

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

effective c++ item35-39

见https://blog.youkuaiyun.com/weixin_44609676/article/details/130382495可以看到,b和pb调用的是同一个虚方法,但是输出到结果却不一样。因为f是虚函数,在运行时才动态绑定需要执行的函数,但是参数却是静态绑定的,在编译期pb的参数就已经是1了。即使把BC的默认参数都换成1,也不推荐这样做。

weixin_44609676的博客 567

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

[翻译] Effective C++, 3rd Edition, 附录 B. 第二和第三版之间的 Item 映射

附录 B. 第二和第三版之间的 Item 映射作者:Scott Meyers译者:fatalerror99 (iTePubs Nirvana)发布:http://blog.youkuaiyun.com/fatalerror99/Effective C++ 的第三版在很多方面与第二版不同,其中最引人注目的是它包含很多新的信息。然而,第二版的大部分内容依然保留在第三版中,虽然经常会改变形式和位置

艺术编程 5819

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)

假设你正在操作一个Rectangle类。每个矩形可以通过左上角的点和右下角的点来表示。为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放入一个辅助结构体中,Rectangle中声明一个指向它的指针就可以了: 1 class Point { // class for repre

小小小程序员的博客 218

读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字

1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息。消息可以以加密或者明文(未加密)的方式被发送。如果在编译阶段我们有足够的信息来确定哪个信息会被发送到哪个公司,我们可以使用基于模板的解决方案: 1 class CompanyA { 2 public: 3 ... 4 void sendCleartext(cons...

weixin_34406086的博客 116

读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)...

假设你正在操作一个Rectangle类。每个矩形可以通过左上角的点和右下角的点来表示。为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放入一个辅助结构体中,Rectangle中声明一个指向它的指针就可以了: 1 class Point { // class for re...

weixin_34064653的博客 121

五次多项式轨迹设计:面向工程师的视觉化运动规划方法

五次多项式是实现C²连续运动轨迹的核心数学工具,其六个自由度可精确约束起点/终点的位置、速度与加速度,从而满足机器人、动画、数控等系统对平滑性与物理可行性的双重要求。原理上,它通过解析求解线性边界方程组获得唯一曲线,避免数值振荡与过拟合;技术价值在于将抽象代数表达转化为可拖拽的几何控制点,显著降低工程直觉建模门槛;典型应用场景包括机械臂路径规划、镜头运镜设计、物理仿真初始化及高等数学教学可视化。本文聚焦‘Quintic’s’这一面向非程序员的交互式设计系统,深度融合曲率圆映射、实时合规校验与多维可视化反馈机

weixin_30715523的博客 435
上一篇: Effective C++ 2e Item36
下一篇: Effective C++ 2e Item38
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值