CUJ C++ Experts Forum: conversation (September 2001)

避坑指南:Abaqus网格划分中90%用户会遇到的5个质量陷阱(附解决方案) 本文深入剖析Abaqus网格划分中90%用户会遇到的5个典型质量陷阱,包括单元扭曲、扫掠网格失败、尺寸梯度控制等,并提供工程级解决方案。通过Python脚本和虚拟拓扑等技巧,帮助用户提升网格质量,确保有限元分析结果的可靠性,适用于CAE工程师和仿真分析师。 阅读详情

 

Conversations: Back to Base-ics
CUJ C++ Experts Forum: conversation (September 2001)

和往常一样,我又在为一个按说应该很简单的设计问题大伤脑筋。可能是劳工节假期刚过还没来得及收心吧,我感觉自己有点迷迷糊糊的。Wendy刚开始休产假,我的靠山也没了。

其实任务只不过是要在一个工程中引入一个新类而已。我已经有一个类,它和想要引入的这个类非常相近。问题是,我不知道该在现有的类和新类之间建立什么关系。当然不能让新类从现有类公有继承,因为二者之间没有IS-A("是一个")的关系。Layering(分层)也不行,因为我需要重写一些虚函数。剩下的选择只有二者取一:要么采用私有继承,模拟Is-Implemented-In-Terms-Of("用...来实现")的关系,要么干脆提取它们的共同功能设计一个新的基类。

百思不得其解之际,我想,大虾此时还不出现更待何时?我让转椅飞快地转了一圈----可是四周一个人也没有。我感到自己有点搞笑,于是还是回到电脑前。"那好吧," 我自言自语,"怎么也得自己搞掂。"

"有时不是那么容易搞掂的哟。" ,我吓了一跳:分明是大虾轻柔的声音在我耳旁响起。我抬起头,大虾正盯着我呢。她继续慢悠悠地问道:"你准备怎么搞掂啊?"

"我正在为这犯愁呢," 我只得承认,同时心跳开始平静下来。"Scott Meyers的第40条款中说,对于一个现有的但概念上不相关的另一个类,如果想利用它的代码,可以采用Is-Implemented-In-Terms-Of的关系来实现[注1]。他举的一个例子是用List来实现Set。" 我把代码给大虾看:

template<class T>
class Set {
private:
    List<T> rep;  // representation for a set
public:
    // ...
};

"但第43条款建议," 我继续说,"如果两个类享有共同的代码,它们就得从一个基类继承。他的例子是两个CartoonCharacter类,即Cricket和Grasshopper,它们都从一个新引入的共同基类Insect继承。" 我把第二个例子给大虾看:

class CartoonCharacter { /* ... */ };
class Insect : public CartoonCharacter { /* ... / };
class Grasshopper : public Insect { /* ... / };
class Cricket : public Insect { /* ... */ };

大虾不禁婉然一笑,"是的。但43条款只适用于两个有关系的类啊。"

"真是个菜鸟," 怎么忘了这一点呢?我不禁小声骂了自己一句。

"这回记住了,我的菜鸟?" 她点点头,补充了一句。现在四周一定有人听得见我们说话,面子还是得保住。

"你说得对。但是," 于是我反击道,"我的困惑在于,我可以将条款43的方法用到条款40的例子中。也就是说,不用List来实现Set;相反,为什么不创建一个新类,比如Container,作为Set和List的基类呢?拿我现在的这个工程来说吧,我完全可以为新类和已有的类设计一个公共基类。"

"哦,我明白了," 大虾点点头,"你的问题实质上是:怎么区分条款40所说的 "利用现有类的代码"和条款43所说的 "共享一部分代码"。表面看来二者确实很相似。" 大虾停下来思考了片刻,"我想你应该按这种思路来考虑:

"通常来说,当要向一个工程添加一个新类,并且已经有一个很相似的类存在时,一般有三种选择:让一个类从另一个类继承;创建一个公共基类让新类和现有的类从它继承;用一个类来实现另一个类。

"最简单的当然是第一种情况----它们之间是IS-A的关系吗?如果是,就让新类从现有的类公有继承,否则就不行。 "

"哦,对了," 我一边在笔记上奋笔疾书一边插话,"这就是Meyers所说的关于C++必须牢记的一点。不过这次不是1066! [注2]"

大虾白了我一眼,继续说,"分析一下所谓的共享或公共代码的本质吧,假如你有现有类的代码的话;如果没有代码,很明显,就不能改变现有类,你只能运用Is-Implemented-In-Terms-Of。但现在这个工程中,你有它的代码,你就得分析一下:它们真的可以共用吗?也就是说,每个类真的会调用同一个函数吗?----这不是指仅仅名字相同的函数,而是真正相同的函数。在Meyers的那个例子中,Cricket和Grasshopper都调用相同的singCustomization函数。它们是真正公用的代码。相反,如果你引入一个新的Container基类,它的insert函数对Set和List来说不一定都可以工作。它们中的某个类,甚至两个类就都得重写自己的insert函数。这种情况下,代码不是真正公共的,使用公共基类就不好。

"继续分析上面的现有类和新类。从概念上来说,它们和某个你认为有用的基类有关系吗?你希望你的Container类怎样有用?拿标准容器类做例子吧,从来就没有什么叫作std::container的类,并且也不可能有----为什么?"

"唔," 我支唔了一声,试探道,"因为接口不相同?"

"这一条理由就足够了。" 她让我过了关。"它们的接口不同;而且,共同性是由特定的使用场合决定的,而不是特定的函数名。仅仅因为想把两个不相关的类联系起来就去捣鼓出一个基类,这有点荒谬;相反,这种情况下应该运用Is-Implemented-In-Terms-Of。"

"等一下," 我插了一句。"Insect类不就是用来联系其它两个类的吗?"

"是的,但Cricket类和Grasshopper类本来就有联系----它们归根到底是在CartoonCharacter的基础上派生出来的。另外,Insect类提供了其它一些功能,Cricket和Grasshopper都要构筑在这些功能之上。所以,Insect类是很有意义的一个类。它提供了一种紧密的、一致的的抽象。

"还要注意," 她继续说,"如果你想访问现有类的保护成员,可能就要考虑使用非公有继承。

"最后,问问自己:使用Is-Implemented-In-Terms-Of会带来多继承吗?要知道,使用公共基类就没有这个问题。多继承天生就比单继承复杂,能用简单的方法为什么不用呢?

我感觉自己有点似懂非懂,看来再听下去就要晕菜了。"那好吧,谢谢你的帮助。我想,我现在知道自己该怎么解决了!"

"哦?是吗?"大虾歪了一下脑袋,"对了,早晨我听Wendy的丈夫说..."

"怎么样?" 我一下兴奋起来。

"一位千金,七斤多,星期一早晨2:18出生的,名叫Jeannine Nancy。"


-----------------------------------------------------
[注1] Scott Meyers. Effective C++, 2nd Edition, Items 40, 42, and 43 (Addison-Wesley, 1997).
[注2] Scott Meyers. Effective C++, 2nd Edition, Item 35 (Addison-Wesley, 1997).

 

手把手教你为RK3588开发板适配RTL8211F网卡:设备树配置与PHY驱动匹配全流程 本文详细介绍了在RK3588开发板上适配RTL8211F千兆以太网PHY芯片的全流程,包括硬件原理图确认、设备树配置与PHY驱动匹配。通过实战案例和调试技巧,帮助开发者解决常见问题并优化网络性能,适用于嵌入式Linux开发中的Ethernet网络功能实现。 阅读详情

相关推荐

Unity游戏开发实战:用Flow Field实现RTS百人军团流畅寻路(附完整代码)

本文深入探讨了在Unity中利用流场寻路技术解决RTS游戏大规模单位移动性能瓶颈的实战方案。通过解析从Dijkstra算法生成成本场、积分场到最终向量场的核心原理,并结合分块、缓存及与DOTS/ECS架构集成的优化策略,实现了百人军团的流畅群体寻路。文章提供了完整的代码示例,助力开发者构建高性能的RTS寻路系统。

weixin_28363123的博客 587

CUJ:标准库:容纳指针的容器

The Standard Librarian: I/O and Function Objects: Containers of PointersMatthew Austernhttp://www.cuj.com/experts/1910/austern.htm?topic=experts--------------------------------------------------

taodm的专栏 2735

Flutter蓝牙开发实战:flutter_blue_plus核心功能与实现原理剖析

本文深入剖析了Flutter蓝牙开发插件flutter_blue_plus的核心功能与实现原理。文章从源码解析入手,详细讲解了蓝牙状态管理、设备扫描、GATT连接、服务发现以及数据读写等关键流程的实现机制,并分享了实战中的性能调优与常见问题解决方案,帮助开发者高效构建跨平台蓝牙应用。

weixin_29014237的博客 444

CUJ:标准库:容纳不完全类型的容器

The Standard Librarian: Containers of Incomplete TypesMatt Austernhttp://www.cuj.com/experts/2002/austern.htm?topic=experts-----------------------------------------------------------------------

taodm的专栏 2142

从稳压管到LDO芯片:一张图看懂线性电源的‘内卷’进化史

本文追溯了从稳压管到LDO芯片的线性电源技术进化历程,详细解析了各阶段的技术突破与局限。重点探讨了现代LDO在超低功耗、高精度控制等方面的创新,并提供了实战选型的黄金法则,帮助工程师在电子设备小型化与低功耗化趋势中做出最优选择。

weixin_42525551的博客 206

IMU标定中的Allen方差

Allen方差 Allen方差是IMU标定任务中的常用工具。IMU标定可以分为确定性误差和随机误差,确定性误差包括:scale、bias、misalignment。随机误差则主要是高斯白噪声和bias随机游走。Allen方差主要用于标定随机误差。 Allen方差获取 Allen方差的计算方法如下: 保持IMU静止, 采集N个数据点。 将N个点定长分组,常用的交叠式Allen方差如下(n=3): 对于每个子集,计算均值后,计算相邻两组的方差,得到的时间-方差曲线即为Allen方差。 Alle

realjc的博客 5737

CUJ:标准库:基于文件的容器 (转)

CUJ:标准库:基于文件的容器 (转)[@more@]The Standard Librarian: File-Based Containers Matt AusternXML:namespace prefix = o ns ...

ciya3282的博客 457

MUSIC算法翻车?Toeplitz矩阵重构如何解决DOA估计中的相干信源难题

本文深入探讨了MUSIC算法在相干信源DOA估计中失效的根本原因,并详细介绍了基于Toeplitz矩阵重构的协方差矩阵修复技术。该方法通过凸优化恢复协方差矩阵的理想结构,有效解决了信号子空间秩亏损问题,从而显著提升了MUSIC算法在相干和多径场景下的分辨精度与稳健性。

a2b3c4d5e的博客 250

CUJ:高效使用标准库:STL中的unary predicate

Effective Standard C++ Library: Unary Predicates in the STL       Klaus Kreft and Angelika Langerhttp://www.cuj.com/experts/1904/toc.htm?topic=experts    标准运行库中的几个泛型算法在运行时使用了一元判定式(unary pr

taodm的专栏 4043

逆向实战:Soul聊天协议加密与Frida绕过检测

本文详细解析了Soul聊天协议逆向分析的全过程,重点介绍了如何利用Frida绕过应用的反调试检测机制。通过静态分析定位关键SO库,并编写Frida脚本动态Hook线程创建函数,成功实现对抗。文章还进一步追踪了基于DES算法的加密流程,并探讨了协议数据结构的解析方法,为移动应用安全研究提供了实战参考。

2w3e4r5t6y的博客 1135

Darknet-Yolov3 移植过程

本教程面向使用寒武纪平台进行深度学习推理任务的开发者。针对当前主流检测网络darknet-yolov3,进行寒武纪平台的移植。开发者对照移植过程,能够利用寒武纪智能处理器设备完成多种场景的目标检测任务。本实验代码基于 Neuware 1.6.1 与 Python 2.7 环境。

shengyin714959的博客 438

CUJ:高效使用标准库:for_each() vs. transform()

Effective Standard C++ Library: for_each() vs. transform()Klaus Kreft and Angelika Langerhttp://www.cuj.com/experts/1902/langer.htm?topic=experts    Note: Article updated on January 5, 200

taodm的专栏 3182

人像抠图 + OpenGL ES 还能这样玩?没想到吧(附带源码)

OpenGL ES 利用抠图算法实现人像留色。

字节流动 3万+

CUJ:高效使用标准库:set的iterator是mutable的还是immutable的?

Effective Standard C++ Library: Are Set Iterators Mutable or Immutable? Portability Issues in Using the Standard Library       Klaus Kreft and Angelika Langerhttp://www.cuj.com/experts/1810/kreft.

taodm的专栏 2644

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

CUJ:标准C++编程:虚函数与内联

标准C++编程:虚函数与内联Josée Lajoie and Stanley Lippman----------------------------------------------------------------------------------[This is the last installment of a column that was being published

taodm的专栏 2637

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Plauger:CUJ停刊互联网是主凶

偶然看到CUJ主编Plauger在Google新闻组上的发言,是关于CUJ停刊原因的,随手翻译了一下,有兴趣的读者可以参考。原文链接:http://groups.google.com/group/comp.lang.c++/browse_frm/thread/2b929da88c4f249d/672e08aBy P.J. Plauger(CUJ停刊)确有此事,但其起因并非众人所称者。杀死CUJ

e人谷龙门阵 8853

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

CUJ:标准库:Allocator能做什么?

http://dev.youkuaiyun.com/Develop/article/17/17946.shtm          CUJ:标准库:Allocator能做什么?     选择自 taodm 的 Bloghttp://www.cuj.com/experts/1812/austern.htm?topic=experts The Standard Librarian: What Ar

skyremember的专栏 1324

CUJ:普及知识:typeint

普及知识: typeintStephen C. Dewhurst  (WQ注:这是比Loki还令我震惊的东西,实在难以译好。先放出来让大家都震惊一下,以后我会修订的。)--------------------------------------------------------------------------------    在最近的系列文章中,我们为 C++语言设计和实现

taodm的专栏 1724

CUJ:高效使用标准库:显式函数模板参数申明与STL

Effective Standard C++ Library: Explicit Function Template Argument Specification and STL A New Language Feature and Its Impact on Old Programming Techniques       Klaus Kreft and Angelika Langerh

taodm的专栏 4688

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 254

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 394

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 349

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 88

【C++——类和对象(上)】筑基篇:以封装奠定面向对象之基

本文系统梳理C++类与对象的核心知识点,涵盖类的定义、访问限定符(public/private)、类作用域、对象实例化及内存布局。重点解析封装思想、this指针机制、空类大小为1字节的原因,以及类与对象在内存中的存储差异。通过对比C语言结构体与C++类,揭示面向对象设计的优势:数据保护、接口统一、命名隔离与代码可维护性提升。内容由浅入深,适合作为学习笔记与复习参考。

2602_95684935的博客 497

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 307

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 450
上一篇: Effective C++ 2e Item50
下一篇: Java Q&A: 抽象类和接口 - 实战练习
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值