C语言实例教程(PDF格式)-第11部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
符
& 按位和 (AND)运算符 二元运算
符
…………………………………………………………Page 77……………………………………………………………
& 取地址运算符 一元运算
符
&& 逻辑和 (AND)运算符 二元运算
符
&= 按位和/赋值运算符 二元运算
符
() 函数调用运算符 –
* 乘法运算符 二元运算
符
* 指针间接引用运算符 一元运算
符
*= 乘法/赋值运算符 二元运算
符
+ 加法运算符 二元运算
符
++ 递增运算符 (注) 一元运算
符
+= 加法/赋值运算符 二元运算
符
减法运算符 二元运算
符
一元负号 一元运算
符
… 递减运算符 (注) 一元运算
符
…= 减法/赋值运算符 二元运算
符
续表2。3
运算 名称 类型
符
…》 成员选择运算符 二元运
算符
…》* 指针成员选择运算符 二元运
算符
…………………………………………………………Page 78……………………………………………………………
/ 除法运算符 二元运
算符
/= 除法/赋值运算符 二元运
算符
《 小于运算符 二元运
算符
右移运算符 二元运
算符
》》= 右移/赋值运算符 二元运
算符
'' 数据下标运算符 –
^ 异或(Exclusive OR)运 二元运
算符 算符
^= 异或(Exclusive OR)/ 二元运
赋值运算符 算符
| 按位或 (Inclusive OR) 二元运
运算符 算符
|= 按位或 (Inclusive 二元运 预
OR)/赋值运算符 算 处
理
符
号
…………………………………………………………Page 79……………………………………………………………
运算符的重载是通过对运算符函数的重载来实现的,对于每一个
运算符@,在C++中都对应于一个运算符函数operator@,其中的符
号 “@”表示表2。3中所列出的运算符,例如运算符 “+”所对应的
运算符函数为operator+,而数组下标运算符 “''”所对应的运算
符为operator''。运算符函数的一般原型为:
type operator@(arglist);
其中type为运算结果的类型,arglist为操作数列表。大多数情况
下,运算符函数可以重载为类的成员函数,也可以重载为全局函
数。在两种不同情况,同一运算符的重载形式所对应的参数表略
有差别。以前面的类matrix的加法运算符为例,我们将加法运算
符函数重载为全局函数,并把它作为类matrix的友元,以便它可
以直接的访问类matrix的受保护成员,其定义如下:
matrix operator+(matrix& A;matrix& B);
上面的运算将类matrix的实例对象A和B进行相加,然后返回一个
类型为matrix的运算结果。
如果上面的运算符函数被重载为类的成员函数,那么它的定义应
该是这样的:
matrix matrix::operator+(matrix& B);
其中参数B代表 “+”右边的操作数,而 “+”左边的操作数总是重
载该运算符函数的类的一个实例对象或其引用,在成员函数
operator+的内部,通过隐含的this指针来对它进行引用。考虑下
面的表达式
C=A+B;
如果运算符函数operator+被重载为友元全局函数
matrix operator+(matrix& A; matrix& B);
则上面的表达式被编译器解释为
C=operator+(A; B);
如果operator+被重载为类matrix的成员函数
matrix matrix::operator+(matrix& B);
则该表达式被解释为
…………………………………………………………Page 80……………………………………………………………
C=A。operator+(B);
初看起来,无论把操作符operator+重载为友元全局函数还是成员
函数,都可以实现同样的功能。的确,在很多情况下是这样的,
但是有些情况下,我们只能选择其中之一。考虑矩阵的数乘运
算,我们可能希望使用下面的表达式
B=3*A;
从数学意义上说,上面的表达式将3乘以A中的每一个元素,然后
将结果赋值给B。假设operator*的定义如下:
matrix matrix::operator*(matrix& A);
即是说我们将operator*函数定义为类的成员函数,这时,编译器
如何解释上面的代码呢?下面的解释方法是行不通的:
B=3。operator*(A);
因为3不是类matrix的一个实例对象,而且,编译器在这种情况下
并不会对左边的操作数作任何类型转换,也就是说,即使你为类
matrix定义了一个构造函数
matrix::matrix(int);
编译器仍然不会将前面的表达式解释为
B=matrix(3)。operator*(A);
因此,将运算符函数定义为类的成员函数是不可能实现我们的要
求的,这时,我们需要将函数operator*定义为全局函数,并且,
将它作为类matrix的友元,如下所示:
matrix operator*(int k; matrix& A);
这时,编译器将前面的表达式解释为
B=operator*(3; A);
由于存在合适的函数原型,因此编译器将调用上面所定义的函数
operator*来进行运算,并将结果赋予B。
上面的叙述容易给人一种感觉,即是说将运算符函数定义为友元
函数要比将它们定义为类的成员函数好得多。事实上很多情况下
也是这样,然而,并不是所有的函数都能够被定义为友元函数,
…………………………………………………………Page 81……………………………………………………………
以下的函数只能被定义为类的成员函数:
operator=
operator()
operator''
operator…》
° 注意:
° 函数operator=只能定义为类的成员函数,但是其它的二元重
合赋值运算符,如?? 、?? 、??和??等却不受此限,请看下面的
代码 :
两个函数中C++中是不同的重载形式。
由编译器自动生成的运算符函数operator所进行的默认操作
是将两个对象中的数据进行按成员拷贝,有一点需要强调的
是,对于其中的指针成员,拷贝的是指针本身,而不是指针
所指向的内容。如果在类中使用了指针成员,这是一个必须
注意的问题,一般来说,在这种情况下,我们必须提供自定
义的拷贝构造函数和以type&为参数的赋值运算符重载函数,
否则很容易引起指针挂起的问题。
表2。5总结了不同运算符的重载方法。比较特殊的是递增运算
符+ + 和递减运算符 ,特殊的原因是它们有两种不同的
形式,即前缀形式和后缀形式。如果区别运算符 “++”和 “
”的两种不同形式呢?我们为此作如下的约定,对于前缀
形式的递增/递减运算符,以和一般的一元运算符同样的方式
将它们重载为
type& type::operator++()
表2。5 不同运算符的重载方法小结
运算符 以友元函数方式进 以成员函数方式进行重载
行重载
一元运算符@ type operator@ type operator@()
(arg)
(不包括递增运 表达式A@或@A等价于
…………………………………………………………Page 82……………………………………………………………
算符++和递减 表达式A@或@A等价 A。operator@()
运算符??) 于operator@(A)
二元运算符@ type operator@ type operator@(arg)
(arg1; arg2)
表达式A@B等价于A。operator@
表达式A@B等价于 (B)
operator@(A; B)
赋值运算符= – type& operator=(arg)
表达式A=B等价于A。operator=
(B)
函数调用运算 type operator()(arg; 。。。)
符 ()
表达式A(arg; 。。。)等价于
A。operator()(arg; 。。。)
注意:
1。 函数调用运算符被当作一个
二元运算符,然而函数调用运
算符函数的参数表却可以拥有
多个参数。
2。 函数调用运算符作用于一个
类的实例对象,而不是一个函
数名。
关于函数调用运算符可以参见
前面的类matrix的实现。假设A
是类matrix的一个实例对象,
则表达式A(1;2)返回矩阵A中第
一行第二列的元素。
下标运算符'' type operator''(arg)
表达式A'arg'等价于
A。operator''(arg)
注意:
除了可以为整数以外,下标运
算符函数的参数arg还可以为任
何类型,比如,你可以创建一
个以字符串为下标的数据列
表。
成员函数运算 type operator…》(arg)
符…》
…………………………………………………………Page 83……………………………………………………………
表达式A…》arg等价于
A。operator…》(arg)
注意:
可以重载成员选择运算符 “
》”,但不可以重载另一个成员
选择运算符 “。”。
type& operator++(type&)
或
type type::operator…()
type operator…(type&)
要注意的是,如果使用将operator++和operator……重载为全
局友元函数,则参数要使用引用类型,这是因为一般来说,
运算符 “++”和 “”都需要修改操作符本身。
对于后缀形式的递增/递减运算符,我们约定使用下面的方式
来进行重载:
type& type::operator++(int)
type& operator++(type&; int)
或
type type::operator…(int)
type operator…(type&; int)