c++学习笔记十三

 运算符重载
     
        1 为自已的类实现运算符
 
          运算符重载
          运算符重载允许把标准运算符(+-*/等)应用于定制数据类型的对像,
        即编写一个函数,重新定义每个运算符,使之每次应用于类的对象时,就执


行         指定的操作
           示例代码如下(如果重新定义<运算符):
              orerator<();
        注:如果是字母运算符,要在关键字和运算符之间有一个空格
          
          可以重载的运算符
          不允许发明新运算符,不能修改优先级和操作个数
                           不能重载的运算符
===========================================================================


=
        运算符                     |                   符号
===========================================================================


=
    作用域解析运算符               |                    ::
===========================================================================


=
    条件运算符                     |                    ?:
===========================================================================


=
    直接成员访问运算符             |                    .
===========================================================================


=
    解除类成员指针引用运算符       |                    .*
===========================================================================


=
    sizeof运算符                   |                    sizeof
===========================================================================


=
      
            注:此外还不能重载预处理指令运算符#
                              标志传送符号    ##


           实现重载运算符(重载<运算符的函数原型)示例代码如下:
           
           class Box{
                  public:
    //比较两个box对象
                     bool  operator<(const Box & Box) const;
                     //参数是运算符的右操作数, 当前指针this 是左操作数    


 
            };
            使用的示例代码如下:
            if(box1.operator<(box2)){ //提高程序的可读性
                cout<<"box1 is less than box2"
                    <<endl;
            }


 
            例子程序
            //头文件Box.h
   #ifndef BOX_H 
            #define BOX_H
   class Box{
 public:
                     Box(double aLength=1.0,double aWidth=1.0,double 


aHeight);//构造器
                  //成员方法
                  double volume() const;
                  double getWidth() const;
                  double getLength() const;
                  double getHeight() const;

                  //重载运算符,定义在函数内效率高
           bool operator<(const Box & aBox) const{
       return volume()<aBox.volume(); 
                  }


   //成员变量
                  private:
                     double length;
                     double width;
                     double height;
            }




             //实现代码 Box.cpp
             #include "Box.h"
             
             //构造器
              Box::Box(double aLength,double aWidth,double aHeight):length


(aLength),width(aWidth),height(aHeight){}
            
             //成员函数
             double Box::volume() const{
                  return length*width:height;
             }
             
             //getXXX()
             double Box::getLength() const{return length;}
             double Box::getWidth() const{return width;}
             double Box::getHeight() const{return height;}
             //有了重载运算符就可以省去compareVolume()
          
          
         全局运算符函数
         inline bool operator<(const Box & Box1,const Box &Box2){
             return  Box1.Volume()<Box2.Volume();
         }
        
         提供对运算符的全部支持
          
          示例化码: bool operator<(double value) const;
           实现部分:
              inline bool Box::operator<(double aValue) const{
                  return volume<aValue;
              }
           还可以实现为:(两个操作数可以是double类型的任意表达式)
              inline bool Box::operator<(const double aValue,const Box & 


aBox) const{
                return  aValue<aBox.volume();
      }
           


         运算符函数术语
         重载运算符函数的一般形式如下:
            返回类型 operator X(类型 右操作数); 
         使用非成员函数实现二元运算符时,其形式如下:
            返回类型 operator X(类型 左操作数,类型 右操作数);  
         如果type类型左操作数不实现为type类的成员, 该函数就必需实现为全局运


算符函数,其型式如下:
             返回类型 operator X(类型 左操作数,类类型 右操作数)
         一元运算符实现为类的成员函数时,一般不要参数(递增和递减例外),其


形式如下:
             类类型& operator Op();
         如果实现为全局运算符时,只有一个参数(操作数)
             类类型& operator Op(类类型 &) 
         
        
        重载赋值运算符   = 
         注:在动态分配内存的类中,如果类的函数在自由存储区内动态分配内存,就


应实现副本的构造函数,赋值运算符和析构函数
           
          实现赋值运算符 (14章代码实例)
           
           
        重载算术运算符
       
          例如重载加号运算符
            头文件的定义 示例代码如下:
              Box operator+(const Box& aBox) const;
            实现文件的定义,示例代码如下:
              inline Box::operator+(const Box& aBox) const{
                     return Box(length>aBox.length?length:aBox.length,
                                width>aBox.width?width:aBox.width,
                                height+aBox.height);
              }
          
           根据一个运算符实现另一个运算符
               重载+=运算符
               inline Box::operator+=(const Box & right){
   length=length>right.length?length:right.length;
                    width=width>right.width?width:right.width;
                    height+=rigth.length;
                    return *this;
               }
             然后在实现+=的基础上再实现+,示例代码如下:
               inline Box::operator+(const Box & aBox) const{
                    return Box(*this)+=aBox;
               }
           
            重载下标运算符[]
               头文件定义如下:
                class TruckLoad(){
                     public:
                         Box operator[] (int index) const;
                };
              
                实现文件定义如下:
                  Box TruckLoad::operator[](int index) const{
                       if(index<0){
                          cout<<endl
                              <<"Negative index";
                              exit(1);    
                       }
                       
                       Package* pPackage=pHead;
                       int count=0;
                       do{
                          if(index==count++){
                              return *pPackage->pBox;
                            }
               
                       }while(pPackage=pPackage->pNext);
       
                       cout<<endl
                           <<"Out of range index";
                       exit(1);
   }


         重载类型转换
            定义一个运算符函数,把类类型转换为另一种类型。
                class object{
                    public:
                      operator Type();//从object类型转换为type
                 };
                 从type1类型到type2类型
                 Type2(const Type1& theObject);
          
          重载递增递减运算符(++,--)
            因为它们放在操作数之前和之后的情况是不一样的,因此每个运算符都需


要两个函数.示例代码如下:
           class Object{
              public:
                Object & operator++();//前缀
                const Object operator++(int);//后缀(防止编译Object ++ ++这


样的表达示)
           }
         
            智能指针(实际上是一个类对象)
               重载解除引用运算符*和间接成员运算符->
                为Box对象定义智能指针,头文件如下(BoxPtr):
                #ifndef BOXPTR_H
                #define BOXPTR_H
                #include "List.h"


                class BoxPtr{
                     //构造器
                    public:
                      BoxPtr(TruckLoad & load);
                      Box & operator*() const;
                      Box * operator->() const;
                      Box * operator->() const;
                      const Box * operator++(int);


                    BoxPtr();
                    BoxPtr(BoxPtr&);
                    BoxPtr& operator=(const BoxPtr&);


   private:
                      Box * pBox;
                      TruckLoad & rLoad;
                }
               
        语句中是怎么调用的 
           BoxPtr pLoadBox(aTruckLoad);
           double  boxVol=pLoadBox->volume();
        第二个语句等价于
           double  boxVol=(pLoadBox.operator->())->volume();
        多出一个operator->()函数必须返回Box * 类型的指针
        
          实现智能指针(BoxPtr.cpp文件)
          
          #include <iostream>
          #include "List.h"
          #include "BoxPtr.h"
          using std::cout;
          using std::endl;
 
          BoxPtr::BoxPtr(){
               pBox=rLoad.getFirstBox();
 }
          
          解除引用运算符,示例代码如下:
  Box& BoxPtr::operator*(){
             if(pBox){
        return *pBox();
              }else{
                cout<<endl<<"Derferencing null BoxPtr";
                exit(1);
              }
           }
          注:如果不支持exit()这种用法,应使用return *pBox()替换
               
          间接成员选择运算符
            Box* BoxPtr::operator->(){
              return pBox;
           } 
          
          使用智能指针 
           #include <iostream>
           #include <stdlib>
           #include <ctime>


           using std::cout;
           using std::endl;  
           
           #include "Box.h"
           #include "List.h"
           #include "BoxPtr.h"
 
           inline int random(int count){
                 return 1+static_cast<int>(count*static_cast<double>


(std::rand())/(RAND_MAX+1.0));
           }
           
           int main(){
              const int dimLimit=100; 
              std::srand((unsigned)std::time(0));
          
              const int boxCount=20;
     Box boxes[boxCount]; 
              //创建20个box对象
    for(int i=0;i<boxCount;i++){
                boxes[i]=Box(random(dimLimit),random(dimLimit),randon


(dimLimit));
                TruckLoad load=TruckLoad(boxes,boxCount);
                //创建一个智能指针,含20个Box对象
                BoxPtr pLoadBox(load);
                Box maxBox=* pLoadBox;
                if(pLoadBox){
                   cout<<endl
                       <<"Volume of first Box is"
                       <<pLoadBox->volume();
                while(++pLoadBox){
                    if(maxBox<* pLoadBox){
                        maxBox=* pLoadBox;
   }
   cout<<endl
                        <<"The larguagest Box is "
                        <<maxBox.getLength()<<"by"
                        <<maxBox.getWidth()<<"by"
                        <<maxBox.getHeight()<<"with volume"
                        <<maxBox.volume();
                }
                }
    }
           }  
            
           重载运算符new和delete(当需要巨量的对象需要分配内存时,而且每个对


象都需要少量内存时)
    
           实现new的标准方法是分配一大块内存,再按需把它分为许多块小内存
           class Data{
               //重载运算符
               public:
                   void * operator new(size_t Size);
                   void operator delete(void * object,size_t size);
          }
         
           要从针对类的new运算符中调用全局new运算符
            void * operator new(){
               pSpace=::new char(size);
  }
            
posted @ 2012-09-20 23:31  retacn_yue  阅读(141)  评论(0编辑  收藏  举报