Chinaunix首页 | 论坛 | 博客
  • 博客访问: 58558
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-23 10:08
个人简介

生活是一种态度!也是一种感悟!

文章分类

全部博文(14)

文章存档

2013年(14)

我的朋友

分类: C/C++

2013-02-23 16:31:09

一、重载操作符

定义:重载操作符是具有特殊名称的函数:保留字 operator 后接需定义的操作符号。重载操作符具有返回类型和形参表。重载操作符的形参数目(包括成员函数的隐式 this 指针)与操作符的操作数数目相同,函数调用操作符可以接受任意数目的操作数。

可重载的操作符:

+  -  *  /  %    ^  &  |  ~  !  =  >  <  +=  -=  *=  /=  %=  ^=  &=  |=  >>  <<  >>=   <<=  ==  !=  >=  <=  &&  ||  ++  --  ->*  ->  []  ()  new  new[] delete  delete []

不可重载的操作符:

::    .*   .   ?:

重载操作符注意事项:

    1.  必须具有一个类类型操作符,不能用于内置类型对象;

    2.  优先级和结合性同内置类型,是固定的;

    3.  对于&& 和 || 重载之后不再具备短路求值特性;

    4.  被定义为类成员的重载操作符函数,隐含了一个this指针;

    5.  一般情况下,被定义为非类成员的重载操作符函数,会声明为类的友元;

    6.  必须作为类成员函数的重载操作符:= (赋值),[](下标),() (调用), ->(成员访问);

    7. 一般作为类成员的函数的重载操作符(但,不必须): 复合赋值类型操作符(如:+=),改变对象状态或与给定类型紧密联系的其他一些操作符(如:++、-- 、*(解引用));

    8. 一般定义为非成员函数的重载操作符:对称的操作符(如:算术操作符、相等操作符、关系操作符、位操作符);

    9. 必须为非类成员函数的重载操作符: 输入输出操作符(<< 和 >> );

 

二、几个特别的重载操作符

  1. 输入输出操作符:

        格式:ostream& operator << ( ostream& os, const ClassType & object ) ;

                  istream& operator >> ( istream& in,  ClassType & object );

    函数形参:第一个形参为 ostream (或istream)对象引用;

                    第二个形参为 类类型的对象引用;

    函数返回值: ostream(或 istream)的对象引用;

    有此可见,输入输出操作符的重载函数必须是非类成员函数,否则,第一个形参就必须是类类型对象引用了。

     输入操作符不同于输出操作符之处为: 输入操作符必须处理 错误输入 和 文件结束 的可能性。

     输入操作符处理检测到输入错误时,需要确保对象处于可用和一致的状态。

     例如:

#include

using namespace  std;


class CA
{
   public:
 CA(): count(0), book("") {}
 CA(int cnt): count(cnt),book("") {}
 CA(const CA& C) : count(C.count), book(C.book) {}

 friend ostream& operator<<( ostream& os, const CA& C);
 friend istream& operator>>( istream& in, CA& C);

 ~CA() {};

   public:
 int count;
 string book;
};

 

ostream& operator<<( ostream& os, const CA& C)
{
 os << C.count << " , last book = " << C.book << "\n"; 
}

istream& operator>>( istream& in, CA& C)
{
 in >> C.book;
 if(in)
  ++C.count;
 else
  cout << " input over ! " << endl;
 return in;
}

int main()
{
 CA A;
 
 cout << A;
 
 while(cin >> A);

 cout << A;

 return 1;
}

 

2. 几个特殊操作符:

复制(=)操作符: ClassType& operator=(ClassType& C);   必须返回*this的引用,类如果没有定义,编译器会合成一个;

下标操作符([]):

       Type & operator [] ( const size_t );

       const Type & operator [] ( const size_t ) const ;

自增自减操作符 ( ++, -- ):

    前缀:

    ClassType & operator ++ ();

    ClassType & operator -- ();

    后缀:

    ClassType operator ++ (int);

    ClassType operator -- (int);

     自增自减操作符的重载分前缀和后缀,定义函数的返回值不同,前缀返回类的引用,后缀返回类的值,并且后缀中形参int,只是用来区分是前缀还是后缀的,因此他没有实际的值,一般编译器提供 0 作为此形参的实参。

 

调用操作符 (() )

    Type operator () ( 形参列表);

 

实例:

 

#include

using namespace  std;

 

class CA
{
   public:

// 构造函数
 CA(): count(0), book("") {}
 CA(int cnt): count(cnt),book("") {}
 CA(string str);

// 复制构造函数
 CA(const CA& C);

// 输入输出操作符

 friend ostream& operator<<( ostream& os, const CA& C);
 friend istream& operator>>( istream& in, CA& C);

// == 和 != 操作符,一般会一起声明;

 bool operator == (const CA& C);
 bool operator != (const CA& C);

 //下标操作符 []
 string& operator [] (const size_t index);
 const string& operator [] (const size_t index) const; 
 //++ --  前缀

 CA& operator ++ ();
 CA& operator -- ();
 //++ --  后缀

 CA operator ++ (int);
 CA operator -- (int);

 // 调用操作符,类对象一般称为函数对象;
 int operator () (vector books);

 ~CA() {};

private:

 int count;
 string book;
 vector bks;

  };
CA::CA(string str)
{
 this->count = 1;
 this->book = str;
 this->bks.push_back(str);
}
CA::CA(const CA& C)
{
 this->count = C.count;
 this->book = C.book;
 this->bks = C.bks;
}
ostream& operator<<( ostream& os, const CA& C)
{

 os << C.count << ", last="<  os << "\n";
 
}

istream& operator>>( istream& in, CA& C)
{
 in >> C.book;
 if(in)
 {
  C.bks.push_back(C.book);
  ++C.count;
 }
 else
  cout << "---- input over ! -----" << endl;
 return in;
}

bool CA::operator == (const CA& C)
{
 if((this->count == C.count) && (this->book == C.book))
  return true;
 return false;
}
bool CA::operator != (const CA& C)
{
 if(*this == C)
  return false;
 else
  return true;
}

string& CA::operator [] (const size_t index)
{
 return this->bks[index];
}
#if 0
int* CA::operator -> ()
{
}
#endif
CA& CA::operator ++ ()
{
 ++this->count;
 this->book = "-no-";
 this->bks.push_back(string("-no-"));
 return *this;
}
CA CA::operator ++ (int)
{
 CA B(*this);

 ++this->count;
 this->book = "-no-";
 this->bks.push_back(string("-no-"));

 return B;
}
CA& CA::operator -- ()
{
 --this->count;
 this->bks.pop_back();
 size_t i=this->bks.end()-this->bks.begin();
 cout << " i= " << i << endl;
 this->book = (*this)[i-1];
 return *this;
}
CA CA::operator -- (int)
{
 CA B(*this);

 --this->count;
 this->bks.pop_back();
 size_t i=this->bks.end()-this->bks.begin();
 cout << " i= " << i << endl;
 this->book = (*this)[i-1];

 return B;
}
int CA::operator () (vector books)
{
 vector::iterator iter = books.begin();
 
 for(; iter != books.end(); ++iter)
 {
  this->count++;
  this->bks.push_back(*iter);
 }

 if(iter != books.begin())
  this->book = *(--iter);

 return this->count;
}

int main()
{
 CA A(string("hello"));
 CA B;
 
 while(cin >> A);  //输入操作符的使用
 cout << "A = " << A;  // 输出操作符的使用
 cout << "B = " << B;
 if(A == B)  // == 使用
  cout << "A==B? yes" <  if(A != B) // !=使用
  cout << "A!=B? yes" <

 cout << "A[0] = " << A[0] << endl;
// cout << "A->count = " << A[0] << endl;

 cout << " ++A = " << ++A ;  // 前缀 ++  使用
 cout << "--A = " << --A ;  // 前缀 --  使用


 

 cout << "A-- =" << A--;  // 后缀 --  使用
 cout << "A = " << A;


 cout << "A++ =" << A++;   // 后缀 ++  使用
 cout << "A = " << A;


 vector str;
 str.push_back("C++");
 str.push_back(string("C#"));
 str.push_back(string("Java"));

 A(str);

 cout << " A(str) = " << A;  // 函数调用()的使用,A称为函数对象;
 return 1;
}

 

 

 

 

 

 

 

阅读(951) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~