作用:
1、直观自然,可以提高程序的可读性
2、体现了C++的可扩充性
3、运算符重载仅仅只是语法上的方便,它是另一种函数调用的方式
4、运算符重载,本质上是函数重载
注意事项:不要滥用重载,因为它只是语法上的方便,所以只有在涉及的代码更容易写、尤其是更容易读时才有必要重载
成员函数:
成员函数原型的格式:
函数类型 operator运算符(参数表);
成员函数定义的格式:
函数类型 类名::operator运算符(参数表)
{
函数体;
}
友元函数:
友元函数的原型:
friend 函数类型operator运算符(参数表);
友元函数定义的格式:
friend 函数类型 类名::operator运算符(参数表)
{
函数体;
}
运算符重载规则:
1、运算符重载不允许发明新的运算符
2、不能改变运算符操作对象的个数
3、运算符被重载后,其优先级和结合性不会改变
4、不能重载的运算符
5、成员函数重载和友元函数重载的选择
(
- 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
- 以下一些双目运算符不能重载为类的友元函数:=、()、[] 、 ->
- 类型转换运算符只能以成员函数方式重载(没有参数,不能指定返回类型)
- 流运算只能以友元的方式重载(为什么:如果是重载双目操作符(即为类的成员函数),就只要设置一个参数作为右侧运算量,而左侧运算量就是对象本身,而 >> 或<< 左侧运算量是 cin或cout 而不是对象本身,所以不满足后面一点,就只能申明为友元函数了)
)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<string.h>
//> < = << >>要会写
using namespace std;
class MyString
{
public:
MyString()
{
this->num = 0;
this->ptr = nullptr;
cout << "调用无参构造函数" << endl;
}
explicit MyString(const char* ptr)
{
this->num = 0;
int len = strlen(ptr);
this->ptr = new char[len + 1];
strcpy(this->ptr, ptr);
cout << "调用有参构造函数" << endl;
}
explicit MyString(const MyString& other)
{
this->num = 0;
int len = strlen(other.ptr);
this->ptr = new char[len + 1];
strcpy(this->ptr, other.ptr);
cout << "调用拷贝构造函数" << endl;
}
MyString(int num)
{
this->num = num;
this->ptr = nullptr;
cout << "调用类型转换构造函数" << endl;
}
MyString(MyString&& other)
{
this->num = 0;
this->ptr = other.ptr;
other.ptr = nullptr;
cout << "调用移动拷贝构造函数" << endl;
}
~MyString()
{
if (ptr != nullptr)
{
delete[]ptr;
}
cout << "调用析构函数" << endl;
}
friend MyString & operator+(const MyString& s1,const MyString& s2);
friend bool operator>(const MyString& s1, const MyString &s2);
friend bool operator<(const MyString& s1, const MyString& s2);
//特殊运算符
//赋值运算符=//如果没有重载(且没有移动拷贝构造函数),系统会默认重载,必须以成员函数重载//注意:默认生成的拷贝是浅拷贝;
MyString& operator=(const MyString& other) //赋值运算符=
{
if (this != &other)
{
int len = strlen(other.ptr);
this->ptr = new char[len + 1];
strcpy(this->ptr, other.ptr);
}
return *this;
}
//移动赋值运算符重载:解决临时对象拷贝开销的问题
MyString& operator=(MyString&& other)//移动赋值运算符重载
{
this->ptr = other.ptr;
other.ptr = nullptr;
return *this;
}
char& operator[](int index) //[]:是双目运算符,但是必须以成员函数重载
{
return (this->ptr)[index];
}
MyString& operator+=(const MyString& other) //+=:利用+实现+=
{
*this = *this + other;
return *this;
}
//!:单目运算符,只能用成员函数重载
bool operator!()
{
return strlen(this->ptr) != 0;
}
//类型转换运算符:static_cast
operator int()
{
return atoi(this->ptr);
}
operator char()
{
return (this->ptr)[0];
}
//流运算符:必须是友元函数重载 cin对象---istream cout对象---ostream
//输出流<<
friend ostream& operator<<(ostream& out, const MyString& s);
//输入流>>
friend istream& operator>>(istream& in, MyString& s);
//i++,++i
int num;
char* ptr;
};
class Test
{
public:
int num;
//++i
Test& operator++()
{
(this->num)++;
return *this;
}
//i++
Test& operator++(int num)//带参的
{
Test temp = *this;
(this->num)++;
return temp;
}
};
MyString& operator+(const MyString& s1, const MyString& s2)
{
int len1 = strlen(s1.ptr);
int len2 = strlen(s2.ptr);
//char* s3 = new char[len1 + len2 + 1];
MyString* s3 = new MyString;
s3->ptr = new char[len1 + len2 + 1];
strcpy(s3->ptr, s1.ptr);
strcat(s3->ptr, s2.ptr);
return *s3;
}
bool operator>(const MyString&s1, const MyString &s2)
{
if (strcmp(s1.ptr, s2.ptr) >0)
{
return true;
}
return false;
}
bool operator<(const MyString& s1, const MyString& s2)
{
if (strcmp(s1.ptr, s2.ptr) < 0)
{
return true;
}
return false;
}
ostream& operator<<(ostream& out, const MyString& s)
{
out << s.ptr;
return out;
}
istream& operator>>(istream& in, MyString& s)
{
string temp;
in >> temp;
const char* mtr = temp.c_str();
s.ptr = new char[temp.size() + 1];
strcpy(s.ptr, mtr);
return in;
}
int main()
{
MyString ms1("hello");
MyString ms2("world");
/*
MyString ms3 = ms1 + ms2;
if (ms1 > ms2)
{
cout << "true" << endl;
}
if (ms1 < ms2)
{
cout << "true" << endl;
}*/
MyString ms3 = ms2;//拷贝构造函数//MyString ms3(ms2);
ms3 = ms2;//赋值运算符
ms3 += ms2;
cout << ms1.ptr << endl;
cout << ms3[2] << endl;
if (!ms3)
{
}
MyString ms4("123456");
int num = static_cast<int>(ms4);
char ch = static_cast<char>(ms4);
cout << num << endl;
cout << ms4 << endl;//流运算符<<输出流运算符 >>输入流运算符
MyString ms5;
cin >> ms5;
Test t1;
t1.num = 5;
t1++;
++t1;
return 0;
}