分类: 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
~CA() {};
private:
int count;
string book;
vector
};
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="<
}
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
{
vector
for(; iter != books.end(); ++iter)
{
this->count++;
this->bks.push_back(*iter);
}
if(iter != books.begin())
this->book = *(--iter);
return this->count;
}
int main()
cout << "A[0] = " << A[0] << endl;
cout << " ++A = " << ++A ; // 前缀 ++ 使用
cout << "A-- =" << A--; // 后缀 -- 使用
A(str);
cout << " A(str) = " << A; // 函数调用()的使用,A称为函数对象;
{
CA A(string("hello"));
CA B;
while(cin >> A); //输入操作符的使用
cout << "A = " << A; // 输出操作符的使用
cout << "B = " << B;
if(A == B) // == 使用
cout << "A==B? yes" <
cout << "A!=B? yes" <
// cout << "A->count = " << A[0] << endl;
cout << "--A = " << --A ; // 前缀 -- 使用
cout << "A = " << A;
cout << "A++ =" << A++; // 后缀 ++ 使用
cout << "A = " << A;
vector
str.push_back("C++");
str.push_back(string("C#"));
str.push_back(string("Java"));
return 1;
}