友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
喜书网 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

C语言实例教程(PDF格式)-第14章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






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)  



也就是说,我们使用一个额外的整型参数来表明所需调用的 

是后缀形式的递增/递减运算符。这样,表达式  



++A  



对于编译器等价于  



A。operator++()  



或  



operator++(A)  


…………………………………………………………Page 84……………………………………………………………

而表达式  



A++  



对于编译器等价于  



A。operator++(0)  



或  



operator++(A; 0)  



运算符 “”与此类似。  



这样,编译器就能有效的区分前缀形式的递增/递减运算符和 

后缀形式的递增/递减运算符,对于Visual C++而言,传递给 

后缀形式的递增/递减运算符函数的整型参数为0,事实上, 

我们可以显式的调用后缀形式的递增/递减运算符函数,如  



A。operator++(3);  



或  



operator++(A; 3);  



这时,所传递的整型参数可以不是0,而且,后缀形式的运算 

符函数operator++也的确可以使用这个参数,这时, “++” 

运算符看起来有点像一个二元运算符,但是,要记住,后缀 

形式的运算符函数operator++只是一个约定,对于C++来说, 

无论使用的是前缀形式还是后缀形式,递增/递减运算符都是 

一个一元运算符,下面的表达式在Visual                 C++中是通不过 

的:  



A++3;  



不要想当然的将它解释为  



A。operator++(3);  



或  



operator++(A; 3);  



  n 注意:  



  n 由表2。3可以知道,用于动态分配内存的运算符new和 


…………………………………………………………Page 85……………………………………………………………

   delete也可以被重载,但是,C++对这两个运算符的默认 

   实现非常之好,而且,由于Win32平台的32位平坦 内存管 

   理机制,在系统物理内存不足时会 自动使用磁盘交换文 

   件,因此,在绝大多数情况下,我们不需要、也不应该 

   重载new和delete运算符,而且,不正确或者说不完善的 

   重载new和delete有可能在动态分配内存时带来难以预料 

   的严重后果。也鉴于这个原因,本书中不再讲述重载new 

   和delete运算符的细节,若读者在程序中的确需要重载 

   它们的话,请参考Visual C++的联机文档或其它的C++文 

   献。  



  n 重载运算符时应该遵从惯例,比如说,我们可以重载运 

   算符 “+”来连接两个字符串,这是合乎我们的日常思维 

   方式的。同样,C++允许我们使用运算符 “”来连接两 

   个字符串,但是,这样的重载方式不会给编程带来
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!