目录
函数原型
返回值 operator + 运算符(形参列表)
{
//运算符重载函数的函数体中应该书写与运算符功能相匹配的函数逻辑。
}
类中重载
例:
//类中运算符重载+
int operator + (const Stu& other)
{
return this->age + other.age;
}
调用:
//调用方式2种:
cout << stu1 + stu2 << endl ;
cout << stu1.operator + (stu1) << endl ;
全局重载
例:
//全局中运算重载。
int operator-(const Stu& stu1, const Stu& stu2)
{
return stu1.getAge() - stu2.getAge();
}
调用:
//调用方式2种:
cout << stu1 - stu << endl ;
cout << operator - ( stu1, stu ) << endl ;
等号(=)重载
编译器默认提供的=号运算符重载,是浅拷贝。
当类中有指向堆区的指针属性时,需要重写=号重载。
类中重载(代码片段):
//对=号重载进行升级
Stu& operator=(const Stu& other)
{
//1.判断是不是本对象进行赋值?
if(this == &other)
{
return *this;
}
this->name = other.name;
this->age = other.age;
//2.判断一下本对象中的属性指针是否指向一块堆上的空间。
if(this->p != nullptr)
{
//先释放
delete []p;
}
//3.开辟新的空间
this->p = new int[1024];
//4.拷贝数据。
memmove(this->p,other.p,sizeof(int[1024]));
return *this;
}
++--重载
++重载(代码片段):
A& operator ++ ( ) //括号为空时,代表前++
{
++sec;
return *this ;
}
--重载(代码片段):
//括号里放一个int,代表后++,只作占位操作符,哑元
A& operator ++ ( int )
{
sec++;
return *this ;
}
不可重载的运算符
1 . (点运算符)通常用于区对象的成员,但是 -> (箭头运算符) 可以重载。
2 : : ( 域名运算符 ) 即类名 + 域运算符,取成员,不可以重载。
3 .* ( 点星运算符) 与 -> * 运算符,也是不可重载。
4 ?: ( 条件运算符) 不可以重载。
5 sizeof 不可以重载。
练习:
+-重载练习:
类代码:
#include <iostream>
using namespace std;
class Stu
{
private:
// string name;
int age;
public:
Stu(int age)
{
this->age = age;
}
Stu& operator-(const Stu& other)
{
this->age -= other.age;
return *this;
}
//注意这两种运算符重载写法,返回值可按需自定
int operator+ (const Stu& other)
{
return this->age + other.age;
}
void shouInfo()
{
cout << "age" << this->age << endl;
}
};
主函数:
int main()
{
Stu stu1(12);
stu1.shouInfo();
Stu stu2(30);
stu2.shouInfo();
//调用方法1:直接相运算
(stu2 - stu1).shouInfo(); //stu2=18
//调用方法2:调用构造函数
stu2.operator-(stu1).shouInfo(); //stu2=6
//=等号重载,是编译器默认生成的,可直接使用
(stu2 = stu1).shouInfo(); //stu2=12
stu2.operator=(stu1).shouInfo(); //stu2=12
cout << stu2 + stu1 << endl; //24
(stu1 = (stu2 - stu1)).shouInfo(); //stu1,stu2 = 0
cout << stu2 + stu1 << endl; //0
}
全局/类中重载练习:
类代码:
#include <iostream>
using namespace std;
class Stu
{
private:
int age;
int * p;
public:
Stu(int age)
{
this->age = age;
this->p = new int [1024] ();
}
~Stu()
{
delete [] p;
p = nullptr;
cout << "析构" << endl;
}
Stu& operator= (const Stu& other)
{
//1.判断是不是本对象进行赋值
if(this == &other)
{
return *this;
}
this->age = other.age;
//2.判断一下本对象中,属性指针是否指向堆区空间
if(this->p != nullptr)
{
//2.1先释放本对象指针
delete [] p;
//2.2开辟空间
this->p = new int [1024];
}else {
this->p = new int [1024] ();
}
//3拷贝数据
memmove(this->p, other.p, sizeof (int [1024]));
return *this;
}
void shouInfo()
{
cout << "age" << this->age << endl;
}
int getAge() const
{
return this->age;
}
};
全局重载运算符:
int operator- (const Stu& stu1, const Stu& stu2)
{
return stu1.getAge() - stu2.getAge();
}
主函数:
int main()
{
Stu stu1(12);
stu1.shouInfo(); //12
Stu stu2(30);
stu2.shouInfo(); //30
stu1 = stu2;
stu1.shouInfo(); //30
//全局重载运算符调用
cout << (operator-(stu1, stu2)) << endl; //0
stu1.shouInfo(); //30
}
综合练习,自定义string类型:
MyString类代码:
#include <iostream>
#include <cstring>
using namespace std;
class MyString
{
private:
//字符串类中的属性指针
char * m_data;
public:
//无参空构造
MyString()
{
this->m_data = new char[1];
this->m_data[0] = '\0';
}
//析构
~MyString()
{
if(m_data != nullptr)
{
delete [] m_data;
}
}
//c++中常量字符串的类型必须使用const char* 来表示一个C风格的常量字符串
//有参构造
MyString(const char * c_str)
{
int len = strlen(c_str);
this->m_data = new char [len +1] ();
memmove(this->m_data, c_str, len);
this->m_data[len] = '\0';
}
//拷贝构造
MyString(const MyString& other)
{
int len = strlen(other.m_data);
this->m_data = new char[len +1];
memmove(this->m_data, other.m_data, len);
this->m_data[len] = '\0';
}
//=号运算符重载函数
MyString operator= (const MyString& other)
{
if(this == &other)
{
return *this;
}
int len = strlen(other.m_data);
//先把自身指针回收,再开辟空间
if(this->m_data != nullptr)
{
delete [] m_data;
this->m_data = new char[len +1];
}else {
this->m_data = new char [len +1];
}
//拷贝
memmove(this->m_data, other.m_data, len);
this->m_data[len] = '\0';
return *this;
}
//[]中括号运算符
char operator[] (int index)
{
if(index < 0 || index >= (int) strlen(this->m_data))
{
cout << "越界了" << endl;
}
return this->m_data[index];
}
//+号运算符重载
MyString operator+ (const MyString& other)
{
int other_len = strlen(other.m_data);
int my_len = strlen(this->m_data);
char * temp = new char[my_len + other_len +1];
memmove(temp, this->m_data, my_len);
memmove(temp + my_len, other.m_data, other_len);
temp[my_len + other_len] = '\0';
return MyString(temp);
}
//获取类中的字符指针的get方法
char * getM_data() const
{
return this->m_data;
}
};
输出流 << 全局重载:
ostream& operator<< (ostream& cout, const MyString& other)
{
cout << other.getM_data();
return cout;
}
主函数:
int main()
{
MyString str1;
MyString str2("hello, world!!");
cout << str2 << endl;
MyString str3 = str2;
cout << str3 << endl;
str1 = str3;
cout << str1 << endl;
cout << str1[3] << endl;
cout << str1[50] << endl;
MyString str4 = "nihao";
cout << str2 + str4 << endl;
cout << str2 << endl;
cout << str4 << endl;
return 0;
}
运行结果: