一、运算符的引出
先看一段代码
class CInt
int main()
{
int arr[] = {1,321};
int len = sizeof(arr)/sizeof(arr[0]);
for(CInt i = 0; i < len; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return 0;
}
这段代码的第六行中的i < len
比较的时候。我们都知道i是一个CInt类型,len是一个整型。也就是说i是一个对象,len是一个变量。这两者在系统中是无法比较的。为了解决这个问题就引入了运算符重载的概念。
二、目的
运算符的重载的目的是让自定义类型满足和内置类型相同的逻辑。
主要是通过函数实现,函数不仅能实现在类中,还能实现在类外。
三、运算符重载写在类中和类外的区别
运算符重载只考虑单目和双目
- 单目
- 类中:this接收操作数,形参不用处理
- 类外:设置一个形参来接收唯一操作数
- 双目
- 类中:this接收左操作数,形参设置一个接收右操作数
- 类外:设置两个参数,第一个形参接收左操作,第二个形参接收右操作数
四、运算符重载机制
不能改变原有运算符的逻辑
不仅能重载运算符还能重载类型(但是不建议重载类型因为不可控)
五、运算符重载的实现
1、模拟复数
class CComplex
{
public:
CComplex(int real, int image)
:mreal(real),mimage(image)
{}
const CComplex operator+ (int val)//实现+号运算符的重载
{
return CComplex(mreal + val, mimage);
}
const CComplex operator+ (const CComplex& rhs)
{
return CComplex(mreal + rhs.mreal, mimage + rhs. mimage)
}
bool operator > (const CComplex& c2)//比较运算符的重载
{
if(mreal > c2.mreal)
return true;
if(mreal == c2.mreal&&mimage > c2.mimage)
return true;
return false;
//return(mreal > c2.mreal || ((mreal == c2.mreal) && mimage > c2.mimage);
}
bool operator == (const CComplex& c2)//实现双等号运算符的重载
{
if(mreal == c2.mreal && mimage == c2.mimage)
return true;
return false;
}
private:
int mreal;//实部
int mimage;//虚部
friend const CComplex operator+(int, const CComplex&);
friend std::ostream& operator<<(std::ostream& out,const CComplex& rhs);
friend std::istream& operator >>(std::istream&, CComplex&)
}
const CComplex operator+(int lhs, const CComplex& rhs)//类外是_cdecl调用约定,类中是_thiscall调用约定。类外调用就没有this指针的存在
{
return CComplex(lhs + rhs.mreal, rhs.mimage);
}
std::ostream& operator<<(std::ostream& out,const CComplex& rhs)//输出流的运算符重载的实现
{
out << rhs.mreal << " -";
out << rhs.mimage;
return out;
}
std::istream& operator >>(std::istream& in, CComplex& rhs)//输入流运算符重载的实现
{
in >> rhs.mreal;
in >> rhs.mimage;
return in;
}
int main()
{
CComplex c1(10,20);
CComplex c2 = c1 +10;//实现+号运算符的重载
CComplex c3 = 10 + c1;
CComplex c4 = c1 + c2;
if(c1 > c3)//实现大于比较运算符的重载
{
std::cout << c1 << std::endl;//实现输出流运算符的重载
}
if(c2 == c3)//实现双等号运算符的重载
{
std::cout << c2 << std::endl;//实现输出流运算符的重载
}
int a;
std::cin >> a;
std::cin >> c1;//实现输入流运算符的重载函数
std::cout << c1 << std::endl;
return 0;
}
2、实现string类
class String//C++ 字符串进行封装
{
public:
String()
{
mptr = new char[1]();
}
String(char* ptr)
{
mptr = new char[strlen(ptr) + 1]();
strcpy_s(mptr, strlen(ptr) + 1, ptr);
}
String(const String& rhs)
{
mptr = new char[strlen(rhs.mptr) + 1]();
strcpy_s(mptr, strlen(rhs.mptr) + 1, rhs.mptr);
}
const String operator+(const char* rhs)
{
char* tmp = new char[strlen(mptr) + strlen(rhs) + 1]();
strcpy_s(tmp, strlen(mptr) + 1, mptr);
strcat(tmp, rhs);
String strtmp(tmp);
delete[] tmp;
return strtmp;
}
bool operator<(const String& rhs)
{
return strcmp(mptr, rhs.mptr) < 0 ? true : false;
}
bool operator!=(const String& rhs)
{
return strcmp(mptr, rhs.mptr) == 0 ? false : true;
}
char& operator[](int index)
{
return mptr[index];
}
~String()
{
delete[] mptr;
mptr = NULL;
}
friend const String operator+(const char*, const String&);
friend std::ostream& operator<<(std::ostream&, const String&);
friend std::istream& operator>>(std::istream&, String&);
private:
char* mptr;
};
const String operator+(const char* lhs, const String& rhs)
{
char* tmp = new char[strlen(lhs) + strlen(rhs.mptr) + 1]();
strcpy_s(tmp, strlen(lhs) + 1, lhs);
strcat(tmp, rhs.mptr);
String strtmp(tmp);
delete[] tmp;
return strtmp;
}
std::ostream& operator<<(std::ostream& out, const String& rhs)
{
out << rhs.mptr;
return out;
}
std::istream& operator>>(std::istream& in, String& rhs)
{
char str[1000];
memset(str, 0, 1000);
in >> str;
delete[] rhs.mptr;
rhs.mptr = new char[strlen(str) + 1]();
strcpy_s(rhs.mptr, strlen(str) + 1, str);
return in;
}
int main()
{
String str1("hello");
String str2 = str1 + "world";
String str3 = "hi" + str1;
if(str1 < str3)
{
std::cout << str1 << std::ebdl;
}
if(str1 != str2)
{
std::cout << str1[0] << std::endl;
}
String str;
std::cin >> str;
std::cout << "str : "<< str << std::endl;
return 0;
}