C++ 运算符重载
一. 概述
C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其新的功能,以满足自身的需求。
运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够用同名的函数来完成不同的基本操作。要重载运算符,需要使用被称为运算符函数的特殊函数形式,运算符函数形式:operatorp
() 后面的p
为要重载的运算符符号
<返回类型说明符> operator <运算符符号>(<参数表>)
{
<函数体>
}
1.1 为什么使用操作符重载?
对于系统的所有操作符,一般情况下,只支持基本数据类型和标准库中提供的class,对于用户自己定义class,如果想支持基本操作,比如比较大小,判断是否相等,等等,则需要用户自己来定义关于这个操作符的具体实现
比如,判断两个人是否一样大,我们默认的规则是按照其年龄来比较,所以,在设计person 这个类的时候,我们需要考虑重载操作符==,而且,根据刚才的分析,比较的依据应该是age或者身高其他属性
那么为什么叫重载呢?这是因为,在编译器实现的时候,已经为我们提供了这个操作符的基本数据类型实现版本,但是现在他的操作数变成了用户定义的数据类型class,所以,需要用户自己来提供该参数版本的实现
1.2 C++哪些运算符允许重载
C++中绝大部分运算符都是可以被重载的
不能重载的运算符只有5个:
.
成员访问运算符*
成员指针访问运算符::
域运算符sizeof
长度运算符?:
条件运算符
1.3 重载运算符的限制
- 只有C++预定义的操作符才可以被重载
- 对于内置类型的操作符,它的预定义不能改变,即不能改变操作符原来的功能
- 重载操作符不能改变他们的操作符优先级
例如”*“和”/“优先级高于”+“和”-“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法强制改变重载运算符的运算顺序 - 重载操作符不能改变操作数的个数
如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两个参数。运算符”+“,”-“,”*“,”&“等既可以作为单目运算符,也可以作为双目运算符,可以分别将它们重载为单目运算符或双目运算符。 - 重载运算符的函数不能有默认的参数
否则就改变了运算符参数的个数,与前面第4点矛盾。 - 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)
也就是说,参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据成员的运算符的性质,如下面这样是不对的:
int operator + (int a,int b)
{
return(a-b);
}
二. 使用重载运算符
2.1 重载 自定义对象的 +
运算符
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
Person operator + (Person &p)
{
Person res;
res.name = this->name + p.name + "的共资产";
res.age = (this->age + p.age) / 2;
res.account = this->account + p.account;
return res;
}
};
int main()
{
Person p1("haiyang1",21,20000);
Person p2("haiyang2", 21, -2000);
// Person p3 = p1.operator+(p2);
Person p3 = p1 + p2;
cout << p3.name << "\n" << p3.account << "\n" << p3.age << endl;
return 0;
}
2.2 重载<<
运算符
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
};
// << 只能全局重载
ostream& operator<< (ostream& cout,Person &p)
{
cout << "name = " << p.name << "age = " << p.age << "account = " << p.account << endl;
return cout;
}
int main()
{
Person p1("haiyang1",21,20000);
Person p2("haiyang2", 21, -2000);
cout << p1 << p2 <<endl;
return 0;
}
2.3 重载 ++i
运算符
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
// 年龄自增
Person& operator++ ()
{
this->age++;
return *this;
}
};
int main()
{
Person p1("haiyang1",21,20000);
cout << (++p1).age << endl; // 22
return 0;
}
2.3 重载 i++
运算符
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
// ++i
Person& operator++ ()
{
this->age++;
return *this;
}
// i++
Person operator++ (int)
{
Person p = *this;
this->age++;
return p;
}
};
int main()
{
Person p1("haiyang1",21,20000);
cout << (p1++).age << endl; // 21
cout << (p1++).age << endl; // 22
return 0;
}
2.4 重载 =
运算符
class Person
{
public:
string name;
int * age;
int account;
Person()
{
}
Person(string name,int *age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
void operator= (Person & p)
{
if (NULL != this->age)
{
delete this->age;
this->age = NULL;
}
this->name = p.name;
this->account = p.account;
this->age = new int(*p.age);
}
};
int main()
{
Person p1("haiyang1",new int(21),20000);
Person p2 = p1;
return 0;
}
2.4 重载 ==
运算符
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
bool operator== (Person & p)
{
return this->name == p.name && this->age == p.age && this->account == p.account;
}
};
int main()
{
Person p1("haiyang1", 21,20000);
Person p2("haiyang1", 21, 20000);
cout << (p1 == p2) << endl; // 1
return 0;
}
2.5 重载 ()
函数调用运算符
仿函数
class Person
{
public:
string name;
int age;
int account;
Person()
{
}
Person(string name,int age,int account)
{
this->name = name;
this->age = age;
this->account = account;
}
void operator() (string text)
{
cout << text << endl;
}
};
int main()
{
Person p1("haiyang1", 21,20000);
p1("haiyang1的账户信息");
Person()("haiyang2的账户信息"); // 匿名函数对象调用仿函数
return 0;
}