More Effective C++:不要重载的操作符

与C一样,C++使用布尔表达式简化求值法(short-circuit evaluation)。这表示一旦确定了布尔表达式的真假值,即使还有部分表达式没有被测试,布尔表达式也停止运算。例如:

char *p;
...
if ((p != 0) && (strlen(p) > 10)) ...


这里不用担心当p为空时strlen无法正确运行,因为如果p不等于0的测试失败,strlen不会被调用。同样:

int rangeCheck(int index)
{
 if ((index < lowerBound) || (index > upperBound)) ...
  ...
}


如果index小于lowerBound,它不会与upperBound进行比较。

很早以前上述行为特性就被反复灌输给C和C++的程序员,所以他们都知道该特性。而且他们也依赖于简短求值法来写程序。例如在上述第一个代码中,当p为空指针时确保strlen不会被调用是很重要的,因为C++标准说(正如C标准所说)用空指针调用strlen,结果不确定。

C++允许根据用户定义的类型,来定制&&和||操作符。方法是重载函数operator&& 和operator||,你能在全局重载或每个类里重载。然而如果你想使用这种方法,你必须知道你正在极大地改变游戏规则。因为你以函数调用法替代了简短计算法。也就是说如果你重载了操作符&&,对于你来说代码是这样的:

if (expression1 && expression2) ...

对于编译器来说,等同于下面代码之一:

if (expression1.operator&&(expression2)) ...
// when operator&& is a
// member function
if (operator&&(expression1, expression2)) ...
// when operator&& is a
// global function


这好像没有什么不同,但是函数调用法与简短求值法是绝对不同的。首先当函数被调用时,需要运算其所有参数,所以调用函数functions operator&& 和 operator||时,两个参数都需要计算,换言之,没有采用简短计算法。第二是C++语言规范没有定义函数参数的计算顺序,所以没有办法知道表达式1与表达式2哪一个先计算。完全与具有从左参数到右参数计算顺序的简短计算法相反。

时间: 2024-10-02 04:41:12

More Effective C++:不要重载的操作符的相关文章

php重载数组操作符

在php中提供了许多接口用于实现一些很特定的功能,比如你想把一个对象当作array使用时,只需要实现ArrayAccess接口,当你想要foreach中能够使用一个对象时,只需要实现Iterator接口,下面给一个例子出来 class BtstoreRoot { /** * 根结点 * @var BtstoreElement */ static $root; } class BtstoreElement implements ArrayAccess, Iterator { /** * 当前所代表

C++中复制构造函数和重载赋值操作符总结_C 语言

前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符的实现要点: 4.复制构造函数的一些细节. 复制构造函数和重载赋值操作符的定义 我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类: 复制代码 代码如下: class CTes

c++ 操作符重载-关于操作符重载的问题

问题描述 关于操作符重载的问题 C++中如果想要对某个类设计一个友元的操作符重载,比如string类型支持string1+string2. 如果返回一个引用的话,编译器会报错.因为返回的类是局部变量,无法引用. 比如: //此函数为List类的友元函数. //template friend List& operator+(List& L1,List& L2); template List& operator+(List& L1,List& L2) { Lis

运算符重载-C++ 操作符重载的内存释放问题

问题描述 C++ 操作符重载的内存释放问题 =操作符重载,给复构造函数进行赋值时的代码如下: MyString & MyString::operator =(const MyString &str) { if(this == &str) return *this; delete []m_pData; //**???????????????????????????? ** m_pData = NULL; m_pData = new char(strlen(str.m_pData) +

C#锐利体验之第八讲 索引器与操作符重载

索引 索引器 索引器(Indexer)是C#引入的一个新型的类成员,它使得对象可以像数组那样被方便,直观的引用.索引器非常类似于我们前面讲到的属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用.下面是典型的索引器的设计,我们在这里忽略了具体的实现. class MyClass{    public object this [int index]    {        get        {            // 取数据        }        set  

C#操作符重载

11.5.1 问题的提出 在面向对象的程序设计中,自己定义一个类,就等于创建了一个新类型.类的实例和变量一样,可以作为参数传递,也可以作为返回类型. 在第七章中,我们介绍了系统定义的许多操作符.比如对于两个整型变量,使用算术操作符可以简便地进行算术运算: class A { public int x; public int y; public int Plus{ return x+y; } } 再比如,我们希望将属于不同类的两个实例的数据内容相加: class B { public int x;

DELPHI8操作符重载的例子

 unit WinForm;interfaceuses System.Drawing, System.Collections, System.ComponentModel, System.Windows.Forms, System.Data;type TWinForm = class(System.Windows.Forms.Form) {$REGION 'Designer Managed Code'} strict private /// <summary> /// Required des

C++中重载+操作符的正确方法

摘要:本文概要性地介绍如何选择正确的策略来为用户定义类型重载 + 操作符. 用户定义的类型,如:字符串,日期,复数,联合体以及文件常常重载二元 + 操作符以实现对象的连接,附加或合并机制.但是要正确实现 + 操作符会给设计,实现和性能带来一定的挑战.本文将概要性地介绍如何选择正确的策略来为用户定义类型重载这个操作符. 考虑如下的表达式:int x=4+2; 内建的 + 操作符有两个类型相同的操作数,相加并返回右值 6,然后被赋值给 x.我们可以断定内建的 + 是一个二元的,对称的,可交换的操作符

C++ 中重载操作符的设计方法

用户定义的类型,如:字符串,日期,复数,联合体以及文件常常重载二元 + 操作符以实现对象的连接,附加或合并机制.但是要正确实现 + 操作符会给设计,实现和性能带来一定的挑战.本文将概要性地介绍如何选择正确的策略来为用户定义类型重载这个操作符. 考虑如下的表达式: int x=4+2; 内建的 + 操作符有两个类型相同的操作数,相加并返回右值 6,然后被赋值给 x.我们可以断定内建的 + 是一个二元的,对称的,可交换的操作符.它产生的结果的类型与其操作数类型相同.按照这个规测,当你为某个用户定义类