友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

C语言实例教程(PDF格式)-第10部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


算,如前一节中的例子,对于类matrix的实例对象,我们希望使 

用下面的这些表达式来直观的进行矩阵的运算:  



A+B+C;  



A*B*C;  



A…B*C;  



而不是去调用相应的函数。再比如对于字符串a和字符串b,我们 

希望使用表达式a+b来进行字符串的连接,就象在Visual Basic和 

Delphi中那样,而不是使用C语言的标准库函数strcat (尽管我们 

所重载的运算符函数内部仍可能是使用strcat来实现的),因为前 

一种方法很显然要直观得多。  



                   表2。3 允许重载的运算符  



            运算    名称              类型  

            符  



            ;    逗号运算符            二元运算 

                                  符  



            !    逻辑否(NOT)运算符      一元运算 

                                  符  



            !=    不等于运算符          二元运算 

                                  符  



            %     取模运算符           二元运算 

                                  符  



            %     取模/赋值运算符        二元运算 

                                  符  



            &     按位和 (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)  



返回目录 上一页 下一页 回到顶部 1 1
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!