运算符重载

运算符重载

让运算符能做一些原来做不了的事情,方便它的使用。

操作数:运算符操作的数字,如1+1,加号操作2个数,为双目运算符

一、运算符重载的概念

//运算符的使用:理解成一个"函数的调用"
1 + 1;
fun(1,1);	//加法功能的函数

1、什么是运算符重载:

1、重载,重新载入,就比如之前那讲的函数重载,对一个已有的函数赋值一个新的定义,因此同一个名 字就可以有不同的含义

2、运算符也是可以重载的,比如cout在输出一个变量的时候,能接受不同类型的数据并输出,他就是重 载了<<运算符,这个就是运算符重载

3、所以运算符指的是对已有的运算符重新定义新的运算规则,已适应不同的数据类型,当然重载之后之 前的运算规则还是有的

2、为什么要进行运算符重载

//1 运算符重载之后可以让运算符去适应不同的数据类型,对于基本数据类型,系统给出了运算符的操作规则,对于自定义数据类型来说,系统是不知道该给出什么规则的。

//例如:
class student
{
	int id;
	int age;
	char name[20];
public:
	student(int id,int age,cosnt char *name)
	{
	this->id=id;
	this->age=age;
	strcpy(this->name,name);
	}
}
	student stu1(1,23,"李四");
	student stu2(2,34,"王五");
	stu1+stu2;//如果是这样相加,那么应该加的是什么呢?编译器是不知道,所以编译器就提供了运算符重载这个机制,让用户自定义运算符的运算符规则

二、运算符重载

运算符重载示例:

class CStudent
{
    int id;
public:
    CStudent(int id)
    {
        this->id = id;
	}
    void operator+(const CStudent& stu)
    {
        cout<< this->id + stu.id << endl;
	}
    
}


CStudent stu1(10);
CStudent stu2(20);
sut1 + stu2;			//隐式调用,运算符重载
sut1.operator+(stu2);	//显示调用,运算符重载


1、运算符重载类中的定义

//1、关键字:operator,通过关键字来定义运算符重载(跟写个函数一样)
//2、定义:
	函数返回值类型 operator 要重载的运算符(参数列表)
	{
	函数体;
	}
//这里我们就把这个运算符的使用,理解为调用函数,只不过和平时的我们用的函数调用不太一样

    
//示例: 这里我们就用上面的那个student类为示例
//重载+号: 我想让两个对象相加,并返回一个整数
	int operator+(const student& stu)
	{
	//其实我想让两个对象里面的两个年龄相加,并返回他们的和
	//这里里面当然也可以写其他的,可以说你想什么功能都可以,返回也自己定
	return this->age+stu.age;
	}
/*注意:因为我们这个运算符是在类中写的,所以是通过对象调用的,那么this指针会占一个参数,而且是第一个参数,也就是说如果我们重载一个运算符,是在类中,而这个运算符是个单目运算符,那么参数列表
就不用写东西了,是双目,那么就需要传另一个参数进来
*/

绝大部分的运算符重载,都可以参考上面这个+号重载

2、运算符重载的特点

1、运算符重载几乎都是出现在类中或者结构体中

2、几乎所有的运算符都可以被重载, .(成员访问运算符)::(域运算符)?: (条件运算符) sizeof (长度运算符) * (成员指针访问运算符) 这些运算符除外

3、运算符可以理解为函数的一个表现

3、运算符重载的注意事项

1、重载运算符:

这个重载的运算符还是满足原来的规则,不能说重载+,结果做的是-的事,这样会使在 运算符重载的运用上增加很大的难度。

2、运算符重载的参数:

指得就是使用这个运算符所需要的操作数,但是运算符重载通常都是在类中或者是结构体中,所以需要对象来调用这个函数,那么this指针会占一个

3、考虑返回值:

不同的运算符有不同的返回值,要记得满足运算符原来的规则

class CStudent
{
    int id;
public:
    CStudent(int id)
    {
        this->id = id;
	}
    CStudent operator+(const CStudent& stu)
    {
        CStudent stu3(this->id + stu.id);
        return stu3;
	}
    
}


CStudent stu1(10);
CStudent stu2(20);
CStudent stu4 = stu1 + stu2;

4、对于运算符重载的调用:

可以直接使用运算符,也可以通过对象 . 出来调用

4、使用友元函数,实现运算符重载

//对象+对象返回一个整型,也就是返回id的和
class CStudent
{
    int id;
public:
	friend int operator+(const CStudent& stu1,const CStudent& stu2);
    //声明为友元
}

//因为这个是直接访问的私有成员,所以需要在类中声明一句
//但是通常,像这些数据一般都有接口可以访问,那么就可以通过接口访问,就不需要这个friend声明了
int operator+(const CStudent& stu1,const CStudent& stu2)
{
    return stu1.id + sut2.id;
}

5、两个不能在类中重载的运算符(左移,右移),和一些运算符重载的示例

class node
{
	int val;
    char* name;
public:
	node(){val=10;}
	friend istream& operator>>(istream& is,node& n);//输入
	friend ostream& operator<<(ostream& os,node& n);//输出
    
    
	/*前后++*/
	node& operator++()//前++
	{	
		this->val++;
		return *this;
	}
    //后++
	node operator++(int)//这里int是占位参,不用传参,只是用来区分前后++的
	{
		node temp=*this;//保存val的值
		this->val++;//val++
		return temp;//返回的是没有++的val的值
	}
	
    /*=*/
    node& operator=(const node& no)
    {
        //如果之前有内存,就先释放
        if(this->name != NULL)
        {
            delete[] this->name;
            this->name = NULL;
        }
        
        this->name = new char[strlen(no.name) + 1];
        strcpy(this->name,no.name);
        return *this;
	}
    
    
	/*伪函数*/
	void operator()()
	{
	cout<<"我是()重载!!"<<endl;
	}
  
    
};


	friend istream& operator>>(istream& is,node& n)//输入
	{
		is>>n.val;
		return is;
	}
	friend ostream& operator<<(ostream& os,node& n)//输出
	{
		os<<n.val;
		return os;
	}
//使用:
	node n;
	cin>>n;//对对象里面的val赋值
	cout<<n;//输出对象里面的val的值
	n();//输出 我是()重载!!

智能指针:

class CStudent
{
    int id;
public:
    CStudent(int id)
    {
        this->id = id;
	}
    ~CStudent()
    {
        cout<<"CStudent释放了"<<endl;
	}
    void getId()
    {
        cout<<id<<endl;
	}
}

/*智能指针:用来托管new出来的对象,让new出来的对象自动释放*/
class CSmartPointer
{
  CStudent* pstu;	//用来托管的指针
 public:
    CSmartPointer(CStudent* pstu)
    {
        this->pstu = pstu;
	}
    ~CSmartPointer()
    {
        cout<<"智能指针释放了"<<endl;
        if(pstu != NULL)
        {
            delete pstu;
            pstu = NULL;
		}
	}
    CStudent* operator->()
    {
        return pstu;
	}
    CStudent& operator*()
    {
        return *pstu;
	}
    
};


//使用
{
    CSmartPointer cmp(new CStudent(5));
    cmp->getId();
    (*cmp).getId();
}

posted @ 2021-11-16 20:11  宣哲  阅读(515)  评论(0编辑  收藏  举报