c++提供运算符重载来完成自定义类对象内置行为的自定义,常见分为如下几类:
1.& . || && ,等有固定含义的不建议重载
2.算术运算、比较运算、输入输出操作 建议设为非成员重载
3.[] * -> () ++ -- 建议设为成员重载
1.算术运算
这里演示了成员和非成员两种方法,建议使用非成员形式重载。注意成员形式返回为引用,非成员形式返回的是新建对象的拷贝。
class CTest1
{
public:
CTest1(int nData=10)
{
m_nData = nData;
}
CTest1& operator-(const CTest1& t);//成员形式的重载
CTest1& operator+=(const CTest1& t);//定义+ -一般需要定义对应的复合赋值函数-= +=
friend CTest1 operator+(const CTest1& t1, const CTest1& t2);//非成员形式的重载,需要定义友元
private:
int m_nData;
};
CTest1& CTest1::operator-( const CTest1& t )
{
this->m_nData -= t.m_nData;
return *this;
}
CTest1& CTest1::operator+=( const CTest1& t )
{
this->m_nData += t.m_nData;
return *this;
}
CTest1 operator+( const CTest1& t1, const CTest1& t2 )
{
CTest1 t;
t.m_nData = t1.m_nData+t2.m_nData;
return t;
}
2.比较运算
这里演示了成员和非成员两种方法,建议使用非成员形式重载,标准容器操作sort、find等需要。
class CTest2
{
public:
CTest2(int nData=10)
{
m_nData = nData;
}
void Display()
{
cout << __FUNCTION__ << " Data: " << m_nData << endl;
}
bool operator<(const CTest2& t)
{
return m_nData < t.m_nData;
}
friend bool operator==(const CTest2& t1, const CTest2& t2);
private:
int m_nData;
};
bool operator==(const CTest2& t1, const CTest2& t2)
{
return t1.m_nData*t2.m_nData == 0;
}
3.输入输出
只能使用非成员形式重载,适用于自定义对象的输入和输出。注意输入重载时,参数不能定义为const,否则无法接受输入。
class CTest3
{
public:
CTest3(int nData=0)
{
m_nData = nData;
}
friend ostream& operator<<(ostream& mycout, const CTest3& t);
friend istream& operator>>(istream& mycin, CTest3& t);//这里t不能为const
private:
int m_nData;
};
ostream& operator<<(ostream& mycout, const CTest3& t)
{
mycout << t.m_nData;//最简单的格式化
return mycout;
}
istream& operator>>(istream& mycin, CTest3& t)
{
mycin >> t.m_nData;
return mycin;
}
4.自增自减
包括前置和后置,常用于类迭代器的访问。注意前置返回为当前对象引用,后置返回的是本次自增自减操作前的对象拷贝。
class CTest4
{
public:
CTest4(int nData=0)
{
m_nData = nData;
}
friend ostream& operator<<(ostream& mycin, const CTest4& t);
CTest4& operator++();//前置
CTest4 operator++(int);//后置,需要多加一个int,返回的是自增之前的对象,不是引用
private:
int m_nData;
};
CTest4& CTest4::operator++()
{
++m_nData;//可在此做上下溢出判断
return *this;
}
CTest4 CTest4::operator++( int )
{
CTest4 t = *this;
++(*this);//调用前置操作
return t;
}
5.索引操作
最常见的就是自定义容器实现时,用索引操作来完成水剂访问。这里分别定义const和非const版本。
class CTest5
{
public:
int& operator[](size_t nIndex);
const int& operator[](size_t nIndex) const;//定义const和非const版本
private:
vector<int> m_vecData;
};
int& CTest5::operator[]( size_t nIndex )
{
if (nIndex <0 || nIndex>= m_vecData.size())
{
throw out_of_range("下标不合法");
}
return m_vecData[nIndex];
}
const int& CTest5::operator[]( size_t nIndex ) const
{
if (nIndex <0 || nIndex>= m_vecData.size())
{
throw out_of_range("下标不合法");
}
return m_vecData[nIndex];
}
6.指针操作
最常见用于智能指针,可参见本篇博客上篇智能指针的实现。
typedef struct tagData
{
int nData1;
double dbData2;
}PtrData;
class CTest6
{
public:
CTest6()
{
pData = new PtrData;
}
~CTest6()
{
if (pData)
{
delete pData;
pData = NULL;
}
}
PtrData& operator*();
PtrData* operator->();
private:
PtrData *pData;
};
PtrData& CTest6::operator*()
{
return *pData;
}
PtrData* CTest6::operator->()
{
return pData;
}
7.函数对象
函数对象不仅能完成回调函数的功能,同时可以在声明对象时指明附加信息,避免多此定义功能类似的函数。同时STL提供了一组标准的函数对象包括算术运算、比较运算和逻辑运算,结合绑定器和求反器可完成强大的功能。
自定义函数对象如下:
class CTest7_lessthan
{
public:
CTest7_lessthan(int nBound)
{
m_nBound = nBound;
}
bool operator()(const int& nData);
private:
int m_nBound;
};
bool CTest7_lessthan::operator()(const int& nData)
{
return nData < m_nBound;
}
使用标准库count_if来计算容器中小于5的元素个数如下:
cout << count_if(vecData.begin(), vecData.end(), CTest7_lessthan(5)) << endl;//自定义函数对象
cout << count_if(vecData.begin(), vecData.end(), bind2nd(less<int>(), 5)) << endl;//标准函数对象和绑定器
cout << count_if(vecData.begin(), vecData.end(), not1(bind2nd(less<int>(), 5))) << endl;//标准函数对象和绑定器、取反器
8.类型转换
可通过非Explicit构造函数完成[到类对象的转换],重载类型转换可以完成[从类对象的转换],如下完成类CTest8到int的转换:
class CTest8
{
public:
CTest8(int nData=0)
{
m_nData = nData;
}
operator int()//没有返回值和参数
{
return m_nData;
}
private:
int m_nData;
};
本文完整演示代码下载链接
原创,转载请注明来自http://blog.csdn.net/wenzhou1219