1、在定义一个类的时候,合理的将操作符进行重载,可以像使用内置类型一样使用我们定义的类。
2、操作符重载有一些原则,我们必须谨记才能避免出错。在之前的章节中有涉及到操作符重载的案例,但是没有系统的讲,想必大家有不少不明白的地方。
3、操作符重载的原则:
3.1、重载操作符的范围:
这地方的new和delete指的是new 和 delete运算符。
3.2、重载的限定:
赋值(=)、下标([])、调用(())、和成员访问箭头(->)等操作符必须定义为成员函数,将这些操作符定义为非成员函数将在编译时标记为错误。
像赋值操作符一样,复合赋值操作符通常应定义为类的成员。与赋值不同的是,不一定非得这样做,如果将复合赋值操作符定义为非成员函数,不会出现编译错误。
改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常应定义为类成员
对称的操作符,如算术操作符,相等操作符,关系操作符,位操作符,最好定义为普通的非成员函数
重载运算符函数可以对运算符做出新的解释,但是原有语意不能改变:
不能改变运算符的优先级
不能改变运算符的结合性
不能改变运算符所需要的操作数
不能创建新的运算符
4、输入和输出操作符
支持I/O操作的类所提供的I/O操作接口,一般应该与标准库iostream为内置类型定义的接口相同,因此,许多的类都需要重载输入和输出操作符。
输入和输出操作符必须定义为非成员函数,因为我们如果将输入或是输出操作符定义为成员函数,则左操作数必须是该类类型的对象,但是显然不能这样用。
5、输入输出操作符重载的例子:
#include <iostream>
#include <string.h>
using namespace std;
class Teacher
{
private:
int age;
double income;
char *szName;
void showTeacher(ostream &out) const;
public:
Teacher(int data = 0,double db_come = 0.0,char *pName = NULL);
~Teacher();
Teacher(const Teacher &m_Teacher);
Teacher &operator = (const Teacher& m_Teacher);
friend ostream& operator<<(ostream &out,const Teacher &m_Teacher);
friend istream& operator>>(istream &in,Teacher &m_Teacher);
public:
int getAge() const;
double getIncome() const;
char* getName() const;
};
void Teacher::showTeacher(ostream &out) const
{
out<<age<<endl;
out<<income<<endl;
out<<szName<<endl;
}
Teacher::Teacher(int data /* = 0 */,double db_come /* = 0.0 */,char *pName /* = NULL */)
{
age = data;
income = db_come;
int m_lenth = 0;
if(NULL!=pName)
{
m_lenth = strlen(pName)+1;
szName = new char[m_lenth];
if(NULL == szName)
{
cout<<"constructor error"<<endl;
}
memset(szName,0,m_lenth);
strcpy_s(szName,m_lenth,pName);
}
else
szName = pName;
}
Teacher::~Teacher()
{
if(NULL!= szName)
{
delete [] szName;
szName = NULL;
}
}
Teacher::Teacher(const Teacher &m_Teacher)
{
age = m_Teacher.age;
income = m_Teacher.income;
int m_lenth = strlen(m_Teacher.szName)+1;
szName = new char[m_lenth];
if(NULL == szName)
{
cout<<"copy constructor error"<<endl;
}
memset(szName,0,m_lenth);
strcpy_s(szName,m_lenth,m_Teacher.szName);
}
Teacher& Teacher::operator=(const Teacher& m_Teacher)
{
if(this != &m_Teacher)
{
age = m_Teacher.age;
income = m_Teacher.income;
int m_lenth = strlen(m_Teacher.szName)+1;
szName = new char[m_lenth];
if(NULL == szName)
{
cout<<"operator = error"<<endl;
}
memset(szName,0,m_lenth);
strcpy_s(szName,m_lenth,m_Teacher.szName);
}
return *this;
}
ostream & operator<<(ostream &out,const Teacher& m_Teacher)
{
m_Teacher.showTeacher(out);
return out;
}
istream & operator>>(istream &in,Teacher &m_Teacher)
{
in>>m_Teacher.age;
in>>m_Teacher.income;
char szTemp[24];
in>>szTemp;
strcpy_s(m_Teacher.szName,24,szTemp);
return in;
}
int Teacher::getAge()const
{
return this->age;
}
double Teacher::getIncome() const
{
return this->income;
}
char *Teacher::getName() const
{
return this->szName;
}
void main()
{
char *pName = NULL;
pName = new char[24];
memset(pName,0,24);
Teacher m_T1(24,12378.9,pName);
cout<<m_T1;
cin>>m_T1;
cout<<"Display Teacher:"<<endl;
cout<<m_T1;
cin.get();
}
一个定义完整的类就是这个样子的,其中实现了对赋值(= )操作符,<< 和 >> 操作符的重载,程序运行的结果如下所示:
当然,在重载输入操作符的时候应该进行输入状态的检查,还要处理错误的状态,这里进行了简化,主要是方便大家查看源码。
我们可以看到,重载了输入和输出操作符,我们可以直接对对象进行操作,如果我们没有重载的话,就只能按照下面的方式来输出了:
cout<<m_T1.age<<endl;
cout<<m_T1.income<<endl;
cout<<m_T1.szName<<endl;
自行比较一下就知道哪种方式简单有效了。当然操作符重载绝对不是为了简单方便,我们在实际应用的时候,更应该把这当做一个标准来执行。