运算符重载---二元运算符重载
- 运算符重载基础
(该文档来自于对传智博客视频的整理)
全局函数和类成员函数的区别
//全局函数
//如果把全局函数转成成员函数,少了一个操作数,通过this指针,被隐藏。
Test add(Test &t1, Test &t2)
{
Test t3(t1.getA()+t2.getA(), t1.getB() + t2.getB()) ;
return t3;
}
//把成员函数转成全局函数,需要多一个参数。。。。
void printAB(Test *pthis)
{
cout<<"a:"<<pthis->getA()<<"b:"<<pthis->getB()<<endl;
}
为什么要有运算符重载
原因: Complex是用户自定义类型。。编译器根本不知道如何进行加减。。。编译器给你提供了一种机制,让用户自己去完成,自定义类型的加减操作。。。。。这个机制就是运算符重载机制。
简单的代码如下:
#include "iostream"
using namespace std;
//a + bi //复数
class Complex
{
public:
friend ostream& operator<<(ostream &out, Complex &c1);
Complex(int a, int b)
{
this->a = a;
this->b = b;
}
void printCom()
{
cout<<a<<" + "<<b<<"i "<<endl;
}
//通过类成员函数完成-操作符重载
Complex operator-(Complex &c2)
{
Complex tmp(a - c2.a, this->b - c2.b);
return tmp;
}
Complex operator+(Complex &c2)
{
Complex tmp(a + c2.a, this->b + c2.b);
return tmp;
}
//通过成员函数完成前置--
Complex& operator--()
{
this->a--;
this->b--;
return *this;
}
//通过成员函数完成前置--
Complex& operator++()
{
this->a++;
this->b++;
return *this;
}
//通过类成员函数完成后置--
Complex operator--(int)
{
Complex tmp = *this;
this->a--;
this->b--;
return tmp;
}
//通过类成员函数完成后置--
Complex operator++(int)
{
Complex tmp = *this;
this->a++;
this->b++;
return tmp;
}
private:
int a;
int b;
};
void main61()
{
Complex c1(1, 2), c2(3, 4);
//全局函数方法去实现操作符重载
//1 承认操作符重载是一个函数
//2 根据操作数,1个操作数 2个操作数,完成函数的参数
//3 根据函数原型,实现需要业务
//Complex c31 = operator+(c1, c2);
Complex c3 = c1 + c2;
//用类成员函数实现-运算符重载
Complex c4 = c1 - c2;
c4.printCom();
//c1.operator-(c2);
{
//问题1 根据类型
int a = 10, b = 1;
int c = a + b;
}
//前置++ 全局函数
++c1;
c1.printCom();
//前置-- 成员函数
--c1;
c1.printCom();
//c1.operator--()
//后置++ 全局函数
c1++; //operator++(c1);
c1.printCom();
//后置-- 类成员函数
c1--; //c1.operator--()
c1.printCom();
system("pause");
}
ostream& operator<<(ostream &out, Complex &c1)
{
//out<<"12345,生活真是苦"<<endl;
out<<c1.a<<" + "<<c1.b<<"i "<<endl;
return out;
}
void main()
{
Complex c1(1, 2), c2(3, 4);
int a = 10;
char *p = "addddd";
cout<<"a"<<a<<endl;
cout<<"p"<<p<<endl;
//Complex自定义类型 。a + bi ab ba
cout<<c1;
//全局函数
//cout<<c1;
//operator<<(cout, c1);
//1
//类成员函数
//因为你没有方法拿到cout这个类的源码。。。。AOP C++
//cout.operator<<(c1);
//2 支持链式编程
cout<<c1<<"abcc";
//函数返回值当左值,要求返回一个引用。。。。。
//cout.operator<<(c1).operator<<("abcd");
//s<<"abcd"
//s cout.operator<<(c1);
//s.operator<<("abcd");
system("pause");
}
编译器如何区分前置++还是后置++?
在C++中重载单目运算符时,会出现前置还是后置的问题,如++,–-等这个时候如何让编译器知道是前置还是后置呢?
其实很简单,只要在重载操作符的参数中加上一个整数型参数,编译器就会自动将这个函数标示为后置,相应的不加则是前置。
- 运算符重载在项目开发中的应用
功能1
[]运算符放在=右边和放在=左边。。。。
所以重载函数原型 int& Array::operator[](int i);
//一下是运算符重载函数
//从数组里面拿元素
int& Array::operator[](int i)
{
return mSpace[i];
}
功能2:
关键1支持一个=
关键点2:
支持多个=号 Array& Array::operator=(Array &a1);
关键点3:释放旧内存
if (this->mSpace != NULL)
{
delete[] mSpace;
this->mLength = 0;
}
}
关键点4:两个函数原型区别
Array& Array::operator=(Array &a1)
Array Array::operator=(Array &a1)
Array& Array::operator=(Array &a1)
{
int i = 0;
if (this->mSpace != NULL)
{
delete[] mSpace;
this->mLength = 0;
}
//a1的所有元素赋给a3
this->mLength = a1.mLength;
this->mSpace = new int[a1.mLength];
for (i=0; i<this->mLength; i++)
{
mSpace[i] = a1[i];
}
return *this;
}
功能3、4
bool operator==(Array &a2);
bool operator!=(Array &a2);
//功能3
//if (a1 == a2) //功能3
bool Array::operator==(Array &a2)
{
if (this->mLength != a2.mLength)
{
return false;
}
for (int i=0; i<this->mLength; i++)
{
if (this->mSpace[i] != a2[i])
{
return false;
}
}
return true;
}
// if (a1 != a2) //功能4
bool Array::operator!=(Array &a2)
{
return !(*this == a2);
}

浙公网安备 33010602011771号