记录本人的学习过程,如果能够帮助到您,是我的荣幸
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
//重载递增运算符
//自定义整型
class myInteger
{
friend ostream& operator<<(ostream& cout,myInteger myint);
public:
myInteger()
{
m_num = 0;
}
//重载前置++运算符
myInteger& operator++()//返回引用 是一直对一个数据进行操作
{
//先进行++运算
m_num++;
//再将自身做返回
return *this;
}
//重载后置++运算符
//void operator++(int) int代表占位参数,可以用于区分前置和后置递增
myInteger operator++(int)//int 表示后置递增
{
//先记录当时结果
myInteger temp = *this;
//后递增
m_num++;
//最后将记录结果做返回
return temp;
}
private:
int m_num;
};
ostream& operator<<(ostream& cout,myInteger myint)//重载左移<<运算符
{
cout<<myint.m_num;
return cout;
}
void test01()
{
myInteger myint;
cout<<++(++myint)<<endl;//包含了左移运算符和前置递增
cout<<myint<<endl;
}
void test02()
{
myInteger myint1;
cout<<myint1++<<endl;//包含了左移运算符和后置递增
cout<<myint1<<endl;
}
int main(){
test01();
return 0;
}
ostream用法
c++中的ostream这个类型,通常作为某个类的友元函数出现,用于<<(左移)操作重载中。
注意:
1、返回值也需要是ostream&形式 —ostream为输出流 &在这里为引用
2、函数定义是输出cout<<___;后面不需要加endl,其他与正常输出一 致
递增重载运算符
1.1 what
operator 是C++的一个关键字,它和运算符(如=)一起使用,表示一个运算符重载函数,在理解时可将operator和运算符(如operator=)视为一个函数名。
使用operator重载运算符,是C++扩展运算符功能的方法。使用operator扩展运算符功能的原因如下:
使重载后的运算符的使用方法与重载前一致
扩展运算符的功能只能通过函数的方式实现(实际上,C++中各种“功能”都是由函数实现的)
1.2 why
对于C++提供的所有操作符,通常只支持对于基本数据类型和标准库中提供的类的操作,而对于用户自己定义的类,如果想要通过该操作符实现一些基本操作(比如比较大小,判断是否相等),就需要用户自己来定义关于这个操作符的具体实现了。
比如,我们要设计一个名为“person”的类,现在要判断person类的两个对象p1和p2是否一样大,我们设计的比较规则是按照其年龄来比较,那么,在设计person类的时候,就可以通过对操作符“”进行重载,来使用操作符“”对对象p1和p2进行比较了(根据前面的分析,实际上比较的内容应该是person类中的数据成员“age”)。
我们上面说的对操作符“”进行重载,说是“重载”,是由于编译器在实现操作符“”功能的时候,已经为我们提供了这个操作符对于一些基本数据类型的操作支持,只不过由于现在该操作符所操作的内容变成了我们自定义的数据类型(如class),而默认情况下,该操作符是不能对我们自定义的class类型进行操作的,所以,就需要我们通过重载该操作符,给出该操作符操作我们自定义的class类型的方法,从而达到使用该操作符对我们自定义的class类型进行运算的目的。
1.3 how
实现一个操作符重载的方式通常分为两种情况:
- 将操作符重载实现为类的成员函数;
- 操作符重载实现为非类的成员函数(即全局函数)。
1.3.1 将操作符重载实现为类的成员函数
在类体中声明(定义)需要重载的操作符,声明方式跟普通的成员函数一样,只不过操作符重载函数的名字是“关键字 operator +以及紧跟其后的一个C++预定义的操作符”,样式如下(person是我们定义的类):
前文介绍出自链接中
原文链接:https://blog.csdn.net/liitdar/article/details/80654324
代码实现如下:
赋值运算符
bool operator==(const person& ps)
{
if (this->age == ps.age)
{
return true;
}
return false;
}
加号(减号)运算符重载
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class person
{
public:
int m_A;
int m_B;
public:
person(){
cout<<"无参构造函数"<<endl;
}
person(int a, int b)
{
this->m_A = a;
this->m_B = b;
}
person(int a,int b)
{
m_A = a;
m_B = b;
}
//成员函数实现 + 号运算符重载
person operator+(const person &p)//关键词(person) + operator + 以及紧跟其后的一个C++预定义的操作符
{
person temp;//调用无参构造 person(){};
temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B;
return temp;
}
};
//全局函数实现 + 号运算符重载
person operator+(const person &p1,const person &p2)
{
person temp(0,0);//调用有参构造函数 person(int a,int b)
temp.m_A = p1.m_A + p2.m_A;
temp.m_B = p1.m_B + p2.m_B;
return temp;
}
void test01()
{
person p1(10,10);
person p2(10,10);
person p3 = p1+p2;//相当于p1.operator+(p2)
cout<<"m_A = "<<p3.m_A<<"m_B = "<<p3.m_B<<endl;
}
int main()
{
test01();
return 0;
}
执行结果:
总结1: 对于内置的数据类型表达式的运算符是不可能改变的
总结2:不要滥用运算符重载
左移运算符重载
作用:可以输出自定义数据类型
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class person
{
friend ostream& operator<<(ostream& cout,person &p);//作为友元类,能够访问类中的私有变量
private:
int m_A;
int m_B;
public:
person(int a,int b)
{
m_A = a;
m_B = b;
cout<<m_A<<" "<<m_B<<endl;
}
};
ostream& operator<<(ostream& cout,person &p)//采用全局函数,重载左移运算符
{
cout<<"m_A: "<<p.m_A<<"m_B: "<<p.m_B;
return cout;
}
void test01()
{
person p(10,10);
cout<<p<<endl;
}
int main()
{
test01();
return 0;
执行结果:
赋值运算符重载
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class person
{
public:
int *m_age;
public:
person(int age)
{
m_age = new int(age);//在堆区开辟空间
}
~person()//释放堆区内存空间,因为是浅拷贝,堆区内存重复释放,程序崩溃
{
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
//person& 要用引用形式
//不返回person的原因是,返回值也会再一次调用拷贝构造,然后再返回值再拷贝,进入了无线拷贝死循环
person& operator=(person &p)//重载 = 号运算符
{
//编译器默认提供浅拷贝
//m_age = p.m_age;
//应该先判断是否有属性在堆区,如果有先释放干净 ,然后再深拷贝
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
//深拷贝
m_age = new int(*p.m_age);
//返回对象本身
return *this;//*this解引用后相当于变量(对象)
}
};
void test01()
{
person p1(18);
person p2(20);
person p3(30);
p3 = p2 = p1;//赋值运算操作,浅拷贝了,p1,p2的指针指向堆区的同一个地址和数据
cout<<"p1's age is : "<<*p1.m_age<<endl;
cout<<"p2's age is : "<<*p2.m_age<<endl;
cout<<"p3's age is : "<<*p3.m_age<<endl;
}
int main()
{
test01();
// int a=10;
// int b=20;
// int c=30;
// c = b = a;
// cout<<"a: "<<a<<endl;
// cout<<"b: "<<b<<endl;
// cout<<"c: "<<c<<endl;
return 0;
}
执行结果:
关系运算符
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class person
{
public:
string m_name;
int m_age;
public:
person(string name,int age)
{
this->m_age = age;
this->m_name = name;
}
bool operator==(person& p)
{
if(this->m_name == p.m_name && this->m_age == p.m_age)
{
return true;
}
else
{
return false;
}
}
bool operator!=(person& p)
{
if(this->m_name == p.m_name && this->m_age == p.m_age)
{
return false;
}
else
{
return true;
}
}
};
ostream& operator<<(ostream& cout,const person &p)
{
cout<<p.m_name;
return cout;
}
void test01()
{
person p1("孙悟空" , 18);
person p2("孙悟空" , 18);
if(p1==p2)
{
cout<<"p1 = p2"<<endl;
cout<<p1<<" "<<p2<<endl;
}
else{
cout<<"!="<<endl;
}
}
int main()
{
test01();
return 0;
}
执行结果: