运算符重载概念
运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
能够重载的运算符
几乎C中所有的运算符都可以重载,但运算符重载的使用时相当受限制的。特别是不能使用C中当前没有意义的运算符(例如用**求幂)不能改变运算符优先级,不能改变运算符的参数个数。这样的限制有意义,否则,所有这些行为产生的运算符只会混淆而不是澄清寓语意。
一.数学运算符重载
以+运算符重载为例
先给出一个例程然后进行分析
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Numbers{
public:
int num1;
double num2;
Numbers(){
this->num1 = 0;
this->num2 = 0;
}
Numbers(int num1, double num2){
this->num1 = num1;
this->num2 = num2;
}
Numbers(const Numbers & numbers){
this->num1 = numbers.num1;
this->num2 = numbers.num2;
}
~Numbers(){
}
//成员函数运算符重载 一元运算符重载
Numbers operator+(const Numbers & numbers){
Numbers * newNumbers = new Numbers;
newNumbers->num1 = this->num1 + numbers.num1;
newNumbers->num2 = this->num2 + numbers.num2;
return *newNumbers;
}
};
//全局函数运算符重载,二元运算符重载
Numbers operator+(const Numbers & numbers1,const Numbers & numbers2){
Numbers numbers;
numbers.num1 = numbers1.num1 + numbers2.num1;
numbers.num2 = numbers2.num2 + numbers2.num2;
return numbers;
}
int main(){
Numbers numbers1(100, 200);
Numbers numbers2(200, 400);
cout << (numbers1+numbers2+numbers1).num1 << endl;;
system("pause");
return EXIT_SUCCESS;
}
分析:第一个运算符重载函数,就是对于+重新进行定义,此中的定义就是,两个成员变量进行相加,之所以只有一个参数是因为,第一个运算符重载函数是一个对象的成员函数。第二个运算符重载函数,参数列表里有两个参数就是因为它不是任何一个对象的成员函数。
二.自增自减运算符重载
例程:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class MyInterger{
friend ostream & operator<<(ostream & cout, MyInterger myInt);
private:
double myInt;
public:
MyInterger(){
this->myInt = 0;
}
MyInterger & operator++(){
++this->myInt;
return *this;
}//前置运算符
MyInterger operator++(int){
MyInterger tempInterger = *this;
++this->myInt;
return tempInterger;
}//后置运算符
MyInterger & operator--(){
--this->myInt;
return *this;
}
MyInterger operator--(int){
MyInterger tempInterger = *this;
--this->myInt;
return tempInterger;
}
};
ostream & operator<<(ostream & cout,MyInterger myInt){
cout << myInt.myInt;
return cout;
}
int main(){
MyInterger myInt;
cout << "myInt:" << --myInt << endl;
cout << "myInt:" << myInt-- << endl;
cout << "myInt:"<<myInt << endl;
system("pause");
return EXIT_SUCCESS;
}
分析:
前置运算符重载函数格式:
返回的类型 operator++(){
//函数体
}
后置运算符重载函数格式:
返回的类型 operator++(int){
//函数体
}
在本节最前面的例程中注释前置运算符处,为何返回的是 MyInterger & 类型呢?是因为在实际运用中有可能会出现++(++i)的情况,也就是模拟int类型的自加,而后面的注释后置运算符处为何返回MyInterger呢?是因为在前置运算符重载中,出现先使用后增加的情况,所以此处返回值是其原来的值,也就是需要存储其原来的值,并返回。
指针运算符(*、->)重载
例程:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person{
public:
Person(){
this->age = 0;
}
Person(int age){
this->age = age;
}
void showAge(){
cout << "age=" << age << endl;
}
~Person(){
cout << "Person析构函数" << endl;
}
private:
int age;
};
class SmartPointer{
public:
SmartPointer(){
this->person = NULL;
}
SmartPointer(Person * person){
this->person = person;
}
~SmartPointer(){
cout << "智能指针析构函数" << endl;
if (this->person != NULL){
delete this->person;
this->person = NULL;
}
}
Person * operator->(){
return this->person;
}//返回一个指针
Person & operator*(){
return *this->person;
}//返回一个对象,用引用返回,就可以直接操作内部的对象,与*指针名,操作相同
private:
Person * person;
};
int main(){
Person * p = new Person;//在堆上开辟的内存空间不会自动释放
Person person;//在栈上开辟的内存空间在函数执行完毕后就会释放
SmartPointer smp(p);
system("pause");
return EXIT_SUCCESS;
}
解释:在注释中。
注:若前面能够理解后面的例程自然可以看懂后面不再对代码进行赘述
三.==,!= ()运算符重载
例程:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class MyInterger{
public:
MyInterger(){
this->myInt = 0;
}
MyInterger(int myInt){
this->myInt = myInt;
}
bool operator==(const int & i){
return i==this->myInt;
}
bool operator==(MyInterger & i){
return this->myInt == i.getInt();
}
bool operator!=(const int & i){
return i != this->myInt;
}
bool operator!=(MyInterger & i){
return this->myInt != i.getInt();
}
int getInt(){
return this->myInt;
}
private:
int myInt;
};
class Add{
public:
double operator()(double i,double j){
return i + j;
}
};
int main(){
MyInterger i;
MyInterger j;
if (i != j){
cout << "正确" << endl;
}
Add add;
cout << add(100, 200) << endl;
system("pause");
return EXIT_SUCCESS;
}
四.左移运算符重载
例程:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Numbers{
public:
int num1;
double num2;
Numbers(){
this->num1 = 0;
this->num2 = 0;
}
Numbers(int num1, double num2){
this->num1 = num1;
this->num2 = num2;
}
};
ostream & operator<<(ostream & cout, const Numbers & numbers){
cout << "num1:" << numbers.num1 << " num2:" << numbers.num2;
return cout;
}
int main(){
Numbers numbers(10, 20);
cout << numbers << endl;
system("pause");
return EXIT_SUCCESS;
}
解释:此处为何要返回ostream 引用呢?,是为了让调用这个做运算符重载后能够继续调用正常的cout输出。