您的位置:首页 > 编程语言 > C语言/C++

c++ 运算符重载和转换

2016-06-05 17:40 483 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: