Effective C++ 2e Item15

ROS TF坐标转换实战:从零搭建机器人坐标系(附常见问题排查) 本文提供了一份ROS TF坐标转换的实战指南,详细讲解了如何从零为机器人搭建完整的坐标系,并深入解析了TF的原理。内容涵盖静态与动态坐标变换的发布、URDF模型使用、以及Rviz和rqt_tf_tree等可视化调试工具。文章还附带了常见问题排查表,帮助开发者快速定位并解决TF树断裂、数据错位等典型问题。 阅读详情

条款15: 让operator=返回*this的引用

C++的设计者Bjarne Stroustrup下了很大的功夫想使用户自定义类型尽可能地和固定类型的工作方式相似。这就是为什么你可以重载运算符,写类型转换函数(见条款M5),控制赋值和拷贝构造函数,等等。他做了这么多努力,那你最少也该继续做下去。

让我们看看赋值。用固定类型的情况下,赋值操作可以象下面这样链起来:

int w, x, y, z;

w = x = y = z = 0;

所以,你也应该可以将用户自定义类型的赋值操作链起来:

string w, x, y, z;               // string是由标准C++库
                                 // “自定义”的类型
                                 // (参见条款49)

w = x = y = z = "Hello";

因为赋值运算符的结合性天生就是由右向左,所以上面的赋值可以解析为:

w = (x = (y = (z = "Hello")));

很值得把它写成一个完全等价的函数形式。除非是个LISP程序员,否则下面的例子会很令人感到高兴,因为它定义了一个中缀运算符:

w.operator=(x.operator=(y.operator=(z.operator=("Hello"))));

这个格式在此很具有说明性,因为它强调了w.operator=, x.operator=和y.operator=的参数是前一个operator=调用的返回值。所以operator=的返回值必须可以作为一个输入参数被函数自己接受。在一个类C中,缺省版本的operator=函数具有如下形式(见条款45):

C& C::operator=(const C&);

一般情况下几乎总要遵循operator=输入和返回的都是类对象的引用的原则,然而有时候需要重载operator=使它能够接受不同类型的参数。例如,标准string类型提供了两个不同版本的赋值运算符:

string&                            // 将一个string
operator=(const string& rhs);      // 赋给一个string

string&                            // 将一个char*
operator=(const char *rhs);        // 赋给一个string

请注意,即使在重载时,返回类型也是类的对象的引用。

C++程序员经常犯的一个错误是让operator=返回void,这好象没什么不合理的,但它妨碍了连续(链式)赋值操作,所以不要这样做。

另一个常犯的错误是让operator=返回一个const对象的引用,象下面这样:

class Widget {
public:
  ...                                           
  const Widget& operator=(const Widget& rhs);   
  ...                                           
};                                              

这样做通常是为了防止程序中做象下面这样愚蠢的操作:

Widget w1, w2, w3;

...

(w1 = w2) = w3;         // w2赋给w1, 然后w3赋给其结果
                        // (给operator=一个const返回值
                        // 就使这个语句不能通过编译)

这可能是很愚蠢,但固定类型这么做并不愚蠢:

int i1, i2, i3;

...

(i1 = i2) = i3;                // 合法! i2赋给i1
                               // 然后i3赋给i1!

这样的做法实际中很少看到,但它对int来说是可以的,对我和我的类来说也可以。那它对你和你的类也应该可以。为什么要无缘无故地和固定类型的常规做法不兼容呢?

采用缺省形式定义的赋值运算符里,对象返回值有两个很明显的候选者:赋值语句左边的对象(被this指针指向的对象)和赋值语句右边的对象(参数表中被命名的对象)。哪一个是正确的呢?

例如,对String类(假设你想在这个类中写赋值运算符,参见条款11中的解释)来说有两种可能:

String& String::operator=(const String& rhs)
{

  ...

  return *this;            // 返回左边的对象
}

String& String::operator=(const String& rhs)
{

  ...

  return rhs;              // 返回右边的对象
}

对你来说,这好象是拿六个一和十二的一半来比较一样为难。实际上他们有很大的不同。

首先,返回rhs的那个版本不会通过编译,因为rhs是一个const String的引用,而operator=要返回的是一个String的引用。当要返回一个非const的引用而对象自身是const时,编译器会给你带来无尽的痛苦。看起来这个问题很容易解决——只用象这样重新声明operator=:

String& String::operator=(String& rhs)   { ... }

这次又轮到用到它的应用程序不能通过编译了!再看看最初那个连续赋值语句的后面部分:

x = "Hello";                     // 和x.op=("Hello");相同

因为赋值语句的右边参数不是正确的类型——它是一个字符数组,不是一个String——编译器就要产生一个临时的String对象(通过Stirng构造函数——参见条款M19)使得函数继续运行。就是说,编译器必须产生大致象下面这样的代码:

const String temp("Hello");      // 产生临时String

x = temp;                        // 临时String传给operator=

编译器一般会产生这样的临时值(除非显式地定义了所需要的构造函数——见条款19),但注意临时值是一个const。这很重要,因为它可以防止传递到函数内的临时值被修改。否则,程序员就会很奇怪地发现,只有编译器产生的临时值可以修改而他们在函数调用时实际传进去的参数却不行。(关于这一点是有事实根据的,早期版本的C++允许这类的临时值可以被产生,传递,修改,结果很多程序员感到很奇怪)

现在我们就可以知道如果String的operator=声明传递一个非const的Stirng参数,应用程序就不能通过编译的原因了:对于没有声明相应参数为const的函数来说,传递一个const对象是非法的。这是一个关于const的很简单的规定。

所以,结论是,这种情况下你将别无选择:当定义自己的赋值运算符时,必须返回赋值运算符左边参数的引用,*this。如果不这样做,就会导致不能连续赋值,或导致调用时的隐式类型转换不能进行,或两种情况同时发生。

忆阻器(二)——忆阻模拟器 除了真实的器件,我们也可以用运放和乘法器来搭忆阻模拟器。这节将介绍数学模型、matlab仿真及multisim仿真。 一、数学模型 忆阻分为磁控和荷控两种,这里介绍三次非线性磁控忆阻模型: {I=W(φ)VW(φ)=a+3bφ2dφdt=V \begin{cases} I=W(\varphi)V \\ W(\varphi)=a+3b \varphi ^2\\ \frac{d \varphi }{dt}=V \end{cases} ⎩⎪⎨⎪⎧​I=W(φ)VW(φ)=a+3bφ2dtdφ​=V​ 这里的WWW 阅读详情

相关推荐

基于Ansys Fluent 的颗粒分离/过滤解决方案

过滤是指通过特殊装置将颗粒移除,将流体提纯净化的过程。过滤的方式很多,应用的物系也很广泛,固-液、固-气、大颗粒-小颗粒等。

sh_djoin的博客 1852

Effective C++ 学习笔记:让operator=返回*this的引用

这节解决的是赋值操作符返回左值还是右值的问题! operator=接受一个对象的引用,同时应该返回一个对象的引用,c++程序员经常犯的一个错误是让operator=返回void,这虽然不是什么错误,但是影响了对象的连续赋值功能。另一个常犯的错误是让operator=返回一个const对象的引用。当要返回一个非const的引用而对象自身是const时,编译器会给你带来无尽的痛苦。右值应该为const

qinmelody的专栏 708

Oracle ERP EBS R12 GL总帐业务方案 系统操作

本文档是Oracle ERP系统的总账管理模块使用手册,主要包含以下内容:1.系统架构设计,详细介绍多组织架构、会计科目设置等核心概念;2.总账日常操作流程,包括凭证录入、审核、过账等全流程管理;3.特殊业务处理,涵盖预算控制、内部往来、合并报表等专项功能;4.期末处理,说明月结、年结的操作步骤;5.系统设置指南,提供会计科目表、权限控制等配置说明;6.附录包含各业务模块的分录示例和系统操作图标说明。本手册适用于财务人员学习和使用Oracle ERP总账系统,重点讲解系统功能要点和实操步骤。

anpeng2019的博客 1888

Effective c++学习笔记——条款10:令operator=返回一个*this的引用

Have assignment operators return a reference to *this 从题目,我们就要记住这条信息,让你的operator=函数return *this; 基本类型int、char等都提供了连锁赋值,并采用右结合律。 int x, y, z; x = y = z = 15; 这句真正被解析为:x = (y = (z = 15)); 为了实现连锁赋值,...

kanwoerzi 186

零差云控 ZeroErr eRob 电机 CAN、CANopen、EtherCAT、ROS2 机器人开发详细教程

TwinCAT 3(Windows 控制与自动化技术)是 Beckhoff 提供的开发平台,可将任何兼容 PC 转变为实时控制系统,用于管理各种类型的工业自动化系统,如 PLC(可编程逻辑控制器)、运动控制、机器人等。

机器人控制与仿真应用 1万+

YOLOv8改进:在C2F模块中引入RepGhost Bottleneck模块

C2F类是YOLOv8中的C2F模块的实现,它包含一个RepGhostBottleneck模块、一个卷积层和一个批归一化层。通过在C2F模块中引入RepGhost Bottleneck模块,我们可以在保持计算效率的同时提升模型的表达能力。这是因为RepGhost Bottleneck模块通过引入重复的卷积核来扩展模型的感受野,从而增加了模型对不同尺度目标的感知能力。RepGhost Bottleneck是一种用于卷积神经网络的改进模块,它可以在保持计算效率的同时提升模型的表达能力。希望以上内容对你有帮助!

IlgCrystal的博客 1307

《Effective C++》条款15、资源管理类提供原始资源的访问

显示转换 在我们的资源管理类中,有时我们需要使用到我们的原始类,所以我们需要在资源管理类中提供对原始资源的访问接口,在智能指针中,都提供了一个get()函数,这个函数使得我们能够获得智能指针内部封装的原始指针,同时智能指针也重载了*运算符和->运算符使得我们可以访问内部指针指向的资源。 如果我们在我们自己的资源管理类中也同样的封装了一个原始类,同样的,我们需要提供我们的原始资源,对于一个字体的管理类。我们同样可以提供一个get()函数返回我们的原始资源。 如果想要获得FontHandle类型的 f

qq_44664843的博客 236

PCL Fast Global Registration 快速全局配准(源码版)

Fast Global Registration(FGR)是一种经典的点云粗配准算法,已集成到Open3D和CloudCompare等软件中。本文介绍了该算法的源码实现及优化方法,包括如何通过修改源码直接读取点云进行配准,而不依赖文件中读取特征描述子。文章还提供了关键参数设置(如最大迭代次数、匹配距离等)。算法实现简单高效,未来计划发布基于纯PCL的版本。源码和论文链接已附上,供开发者参考。

点云侠的博客 383

【复读EffectiveC++15】条款15:在资源管理类中提供对原始资源的访问

APIs往往要求访问原始资源,所以每一个RAII类应该提供一个“取得其所管理的资源”的办法。 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。

weixin_51122602的博客 679

Android性能分析——GPU资源耗尽分析(二十六)

本文分析了Android车机系统中GPU资源耗尽导致应用闪退的案例。通过日志定位到EGL_BAD_ALLOC错误,表明系统无法分配足够图形资源创建EGL上下文。问题主要发生在渲染线程初始化EGL环境时,根源在于车机系统对GPU资源的严格限制(如EGLContext数量、GPU内存等)。文中详细解读了SkiaOpenGLPipeline和EglManager的源码调用链路,指出createContext()函数中的致命断言是崩溃的直接原因,并提出了移除断言、增加重试机制、优雅降级等改进方案。该案例揭示了资源受

小旭的专栏 677

【实战教程】OpenClaw接入MySQL数据库实战指南

本文介绍了在虚拟机Ubuntu中访问宿主机Win11中MySQL数据库的配置方法,重点包括创建远程用户、权限配置和安全设置。首先在MySQL中创建具有只读权限的用户并刷新权限,然后调整服务器设置允许远程连接。文章还提供了某金融机构财富管理系统的数据库设计方案,包含理财产品表、客户表和份额表的核心结构,其中金额字段使用DECIMAL类型确保精度,并设置唯一键约束。文末强调测试环境配置完成后应恢复安全更新模式以保障生产环境安全。

海兰 8700

C++中operator关键字(重载操作符)

C++中operator关键字(重载操作符)

ken2232的博客 2637

C++ int转四字节数组

字节转换

我不是码农的博客~~~ 974

Effective C++ 2e Item32

条款32: 尽可能地推迟变量的定义是的,我们同意C语言中变量要放在模块头部定义的规定;但在C++中,还是取消这种做法吧,它没必要,不自然,而且昂贵。还记得吗?如果定义了一个有构造函数和析构函数的类型的变量,当程序运行到变量定义之处时,必然面临构造的开销;当变量离开它的生命空间时,又要承担析构的开销。这意味着定义无用的变量必然伴随着不必要的开销,所以只要可能,就要避免这种情况发生。正如我

lostmouse的专栏 910

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

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

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Effective C++ 2e Item16

条款16: 在operator=中对所有数据成员赋值条款45说明了如果没写赋值运算符的话,编译器就会为你生成一个,条款11则说明了为什么你会经常不喜欢编译器为你生成的这个赋值运算符,所以你会想能否有个两全其美的办法,让编译器生成一个缺省的赋值运算符,然后可以有选择地重写不喜欢的部分。这是不可能的!只要想对赋值过程的某一个部分进行控制,就必须负责做赋值过程中所有的事。实际编程中,这意味着写赋

lostmouse的专栏 979

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Effective C++ 2e Item17

 条款17: 在operator=中检查给自己赋值的情况做类似下面的事时,就会发生自己给自己赋值的情况:class X { ... };X a;a = a;                     // a赋值给自己这种事做起来好象很无聊,但它完全是合法的,所以看到程序员这样做不要感到丝毫的怀疑。更重要的是,给自己赋值的情况还可以以下面这种看起来更隐蔽的形式出现:

lostmouse的专栏 966

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Modern Effective C++ item 15:尽可能的使用constexpr

当constexpr应用于函数时,表示函数可以在编译期执行,因为参数也是编译期常量。常量表达式构造函数拥有和常量表达式函数相同的退化特性,当它的实参不是常量表达式的时候,构造函数可以退化为普通构造函数,当然,这么做的前提是类型的声明对象不能为常量表达式值。正常工作,因为 10 是一个常量表达式,size(10) 可以在编译时计算其结果,并用于初始化 constexpr 变量 s_constexpr。constexpr还能定义一个常量表达式函数,即constexpr函数,常量表达式函数的返回值可以在编译。

_ 1120

c++ item

C++书单: 1:第一本   基础好一些的,可以看Stanley B. Lippman的C++ Primer,基础不太好的话,可以看Stanley B. Lippman的  Essential C++ 2:第二本   Pike和Kernighan的The Practice of Programming 3:第三本   Bruce Eckel写的、台湾候捷译的Thinking in C+

u012526180的专栏 3020

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

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

艺术编程 5819

effective c++ item 25-29

effective c++

weixin_44609676的博客 449

Effective C++ Item 27 少做转型操作

旧式转型 (T) expression 或 T (expression) 新式转型 const_cast<T>(expression) 通常被用来将对象的常量性转除(cast away the constness) dynamic_cast<T>(expression) 执行“安全向下转型”,也就是用来决定某对象是否归属继承体系中的某个类型。 reinterpret_cast<T>(expression) 执行低级转型 //不太懂?? static_cast<T>(expression) 强迫隐式转换

1098

Effective C++ Item 15 在资源管理类中提供对原始资源的访问

经验:APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的办法。 对原始资源的访问可能经由显式转换或隐匿转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。

880

读书笔记 effective c++ Item 48 了解模板元编程

1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行。你可以想一想:一个模板元程序是用C++实现的并且可以在C++编译器内部运行的一个程序,它的输出——从模板中实例化出来的C++源码片段——会像往常一样被编译。 2. 使用TMP的优势 如果这没有冲击到你,是因为你没有足够尽力去想。   C++不是...

HarlanC的专栏 200

读书笔记 effective c++ Item 5 了解c++默认生成并调用的函数

1 编译器会默认生成哪些函数  什么时候空类不再是一个空类?答案是用c++处理的空类。如果你自己不声明,编译器会为你声明它们自己版本的拷贝构造函数,拷贝赋值运算符和析构函数,如果你一个构造函数都没有声明,编译器同样会为你声明一个默认拷贝构造函数。这些所有的函数会是public和inline的(Item30)。因此,如果你写了下面的类: 1 class Empty{}; 本质上来说和下面的类...

HarlanC的专栏 179

读书笔记 effective c++ Item 13 用对象来管理资源

正文回到顶部1.不要手动释放从函数返回的堆资源假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来,1classInvestment{...};//rootclassofhierarchyof23//investmenttypes进一步假设这个程序库通过一个工厂函数(Item 7)来...

weixin_34007886的博客 64

伺服压机软件架构拆解:上位机与下位机的职责划分与工程实践

在工业自动化控制系统中,软件架构的分层设计直接决定设备的稳定性与开发效率。特别是对于伺服压机这类对实时性要求严苛的设备,通常将系统划分为上位机与下位机两部分,本质是按控制周期和功能边界进行职责切分。下位机承担毫秒级的位置、速度与压力闭环控制及安全保护,保证实时性不受操作系统干扰;上位机则专注于配方管理、数据追溯与人机交互等非实时业务,两者通过Modbus TCP或自定义TCP协议实现松耦合通信。合理区分上位机管控层与下位机实时层的架构边界,是设备稳定运行的关键前提。这种分层思想不仅适用于伺服压机,也广泛适用

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值