现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C++运算符重载

2012-07-07 07:51 工业·编程 ⁄ 共 2396字 ⁄ 字号 暂无评论

1.运算符重载的概念:
   可以重新定义已有的运算符,使其完成自定义的功能。
 
2.运算符重载的作用:
   运算符重载与函数重载相似,其目的是增加运算符函数,让运算符具有另一种功能。

3.运算符重载的实质:
   因为使用运算符实际就是一种函数调用,所以运算符重载实际上就是函数重载,同函数重载一样属于静态多态性(编译时的多态性,静态绑定,早起联编).
   而虚函数属于动态多态性(运行时的多态性,动态绑定,滞后联编).
 
4.运算符重载的规则:
只能重载已有的且被允许重载的运算符。
重载之后,运算符的优先级和结合性不会改变,也不能够改变。
重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型.

5.运算符的两种重载方式:
当运算符重载为类的成员函数时,函数的参数个数比原来的参与运算的运算数个数要少一个(后缀++、--除外).重载一元运算符没有参数;重载二元运算符只有一个参数。
    一般基于某个对象调用成员函数,这个对象是一个隐含的操作数,就是被调用的运算符函数的一个操作数,而且是第一操作数.
当运算符重载为类的友元函数时,参数个数与原运算数的个数相同。
    由于友元函数不是成员函数,没有this指针,所以重载二元运算符(双目运算符)时,要有两个参数;重载一元运算符(单目运算符)时,要有一个参数。
   
  注意:
   成员函数的调用只能够通过成员函数所属的类的对象来调用,也就是说被重载的运算符的第一操作数的类型是确定的,是隐含的,不可改变。
   有些运算符必须用友元函数重载,比如:"<<( 输出运算符 )"和">>( 输入运算符 )"。
 
6.单目和双目运算符重载的重载:
  一般来讲,单目运算符最好重载为成员函数,而双目运算符则最好重载为友元函数。
 
  (1).单目运算符重载:
   a.可重载为没有参数的成员函数或者带有一个参数的非成员函数(友元函数),其参数必须是用户定义类型的对象或者是对该对象的引用。
  b.单目运算符++和--,重载时,由于有前缀和后缀的差别,其参数个数遵照以下格式规定:
   <函数类型> operator ++( );     //前缀运算符重载
   <函数类型> operator --( );    //前缀运算符重载
   <函数类型> operator ++(int);  //后缀运算符重载
   <函数类型> operator --(int);  //后缀运算符重载
  由于前缀++,--时先修改,后使用,所以修改和返回的都是同一个对象.
  由于后缀++,--时先使用,后修改,所以带一个参数,创建临时对象来保存对象原来的值.
  
  (2).双目运算符重载:
    可以重载为带一个参数的成员函数或者带两个参数的友元函数。
 
7.几个常用运算符的重载举例:

   (1).重载赋值运算符和拷贝构造函数的必要性?
   由于系统默认的赋值方式和默认的拷贝构造函数是一种“浅复制”,它将对象数据成员“逐位”进行复制赋值。当类中包含指针成员的时候,它并不会将指针所指向的内存单元的内容复制一份,它只会将指针成员变量的值复制给新对象的指针成员。显然在数据成员有指针的情况下,需要用户自己定义拷贝构造函数和赋值运算符。否则就会造成指针悬挂和野指针问题。
   赋值运算符的重载形式:
   CPerson &operator=( const CPerson &oCPerson )
   {
   if (this == &oCPerson) //1、判断是否自己赋值给自己
   {
      return *this; //是,则返回自己
   }
   delete m_lpszName; //2、释放自己的内存空间
   m_lpszName = NULL; //将其置为NULL是一种好习惯。
   m_lpszName = new char[strlen( oCPerson.m_lpszName )+1];
   strcpy( m_lpszName, oCPerson.m_lpszName );  //3、复制
   delete m_lpszSex; //释放自己的内存空间
   m_lpszSex = NULL;
   m_lpszSex = new char[strlen( oCPerson.m_lpszSex )+1];
   strcpy( m_lpszSex, oCPerson.m_lpszSex );  //复制
   return *this; //4、返回赋值后的对象。
   }
   拷贝构造函数的重载形式:
   CPerson( const CPerson &oCPerson )
   {
   m_lpszName = new char[strlen( oCPerson.m_lpszName )+1];
   strcpy( m_lpszName, oCPerson.m_lpszName );
   m_lpszSex = new char[strlen( oCPerson.m_lpszSex )+1];
   strcpy( m_lpszSex, oCPerson.m_lpszSex );  
   }

   (2).输出运算符(<<)和输入运算符(>>)的重载:
   "<<"和">>"只能够用友元函数来重载。
   a.输出运算符(<<)的重载:
    第一操作数是标准类类型ostream的对象的引用,比如:“&cout”。
    第二操作数是本类的对象。为了保证输出运算符(<<)的连用性,重载函数的返回类型应该为ostream的引用。
    friend ostream &operator << ( ostream &cout, 类类型 obj );
   b.输入运算符(>>)的重载:
    第一操作数是标准类类型istream的对象的引用,比如:“&cin”。
    第二操作数是本类的对象。
    为了保证输入运算符(>>)的连用性,重载函数的返回类型应该为istream的引用。
    friend istream &operator >> ( istream &cin, 类类型 &obj );

给我留言

留言无头像?