c++实现运算符的重载(解释最全)

一、简介

        运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能。这个函数叫做运算符重载函数(常为类的成员函数)。用函数的方式实现了(+ - * / []数组 && || 逻辑 等)运算符的重载。

二、算数运算符的重载

class test8
{
    //声明c_score为私有成员,所以要声明友元函数
    //+ - * / 一个道理,这里只对 + - 进行演示
    //重写了很多,是为了能够实现不同的应用场景
	friend test8& operator-(test8& t, float score);
	friend test8& operator-(float score, test8& t);
	friend test8& operator-(test8& t1, test8& t2);
private:
	float c_score;
public:
    test8& test8::operator+(float score);
}

//!通过成员函数实现运算符重载,能够实现 t+2+5+6的运算
test8& test8::operator+(float score) {
	//!if (this == nullptr) return; 不知道return啥
	c_score += score;
	return *this;
}

//!通过全局函数实现运算符重载
//可以实现 t - 2 - 3
test8& operator-(test8 &t,float score) {
	t.c_score -= score;
	return t;
}
//可以实现 52 - 41 -t
test8& operator-(float score, test8 &t) {
	t.c_score -= score;
	return t;
}
//可以实现 t - 20 - t
test8& operator-(test8& t1, test8& t2) {
	t1.c_score -= t2.c_score;
	return t1;
}

三、比较运算符的重载

        返回值一定是bool

class test8
{private:
	float c_score;
//重载 == < > != >= <=
    bool operator==(const test8& t) {
	    if (c_score == t.c_score)return true;
	    return false;
}

四、下标运算符的重载

        返回对象一定是string&类型

class test8
{private:
	string c_boys[3];
    //!下标运算符的重载
    //非常对象用的函数
    string& operator[](int i) {
	    return c_boys[i];
}

五、赋值运算符的重载

        若不重写赋值运算符,系统会提供一个浅拷贝的赋值,这里作者写了一个提供深拷贝的赋值

class test8
{
public:
	string c_name;
	int c_age;
private:
	float c_score;
	string c_boys[3];
    //!重载赋值运算符
    test8& operator=(test8 g) {
	    if (this == &g) return *this;//代表自己给自己赋值

	    c_age = g.c_age;
	    c_name = g.c_name;
	    c_score = g.c_score;

	    if (g.c_ptr == nullptr) {
		    if(c_ptr != nullptr){
			    delete c_ptr;
			    c_ptr = nullptr;
		    }
		
	    }
	    else {
		    if (c_ptr == nullptr) {
			    c_ptr = new int;
		    }
		    memcpy(c_ptr, g.c_ptr, sizeof(int));
	    }
	    
	    return *this;
}

六、左移运算符的重载

class test8
{
public:
	string c_name;
	int c_age;
private:
	float c_score;
	string c_boys[3];
}
  //!对<<进行重载实现自定义类的输出,只能使用全局函数实现
ostream& operator<<(ostream& cout, test8& t) {
	cout << "-->  c_name " << t.c_name << endl;
	cout << "-->  c_age " << t.c_age << endl;
	cout << "-->  c_score " << t.c_score << endl;
	cout << "-->  c_ptr " << t.c_ptr << endl;
	cout << endl;
	return cout;
}

七、new和delete的重载写法固定

class test8
{
public:
	string c_name;
	int c_age;
    //!重载new运算符,固定的写法
    void* operator new(size_t size) {
	    cout << "调用了类的new函数" << endl;
	    void* ptr = malloc(size);
	    cout << "申请到的内存地址是   " << ptr << endl;
	    return ptr;
    }
    //!重载delete运算符
    void operator delete(void* ptr) {
	    cout << "调用了类的delete函数" << endl;
	    if (ptr == 0) return;
	    free(ptr);
    }

private:
	float c_score;
	string c_boys[3];
    
}

八、一元运算符的重载

常见的一元运算符有:

  • 递增和递减运算符:++ 和 --,用于对操作数进行增加或减少 1。
  • 正负号运算符:+ 和 -,用于表示正负数。
  • 逻辑非运算符:!,用于对布尔值进行取反。

以++运算符为例子讲解,未重载++运算符可以实现的功能,想必大家都很熟悉,代码如下:

int main() {
	int a1,a2;
	a1 = 0;
	a2 = 0;
	int b = a1++;
	int c = ++(++a2);
	cout << "-->a1:  " << a1 <<"  -->b   "<<b << endl;
	cout << "-->a2:  " << a2 <<"  -->c   "<<c << endl;
	return 0;
}

运行结果,具体实现流程就不讲解了。

让我们来看++的重载,注意一元运算符的重载只能在成员函数中进行代码如下:

class test11 {
public:
	int c_rank;

	//使用初始化列表对c_rank进行初始化
	test11() :c_rank(0) {
	}

	//重载++运算符
	void operator++() {
		c_rank += 1;
	}
};
//重载<<运算符实现输出
ostream& operator<<(ostream& cout,const test11& t) {
	cout << "  -->c_rank   " << t.c_rank << endl;
	return cout;
}

int main() {
	test11 a,b;
	++a;
	cout << a;
	return 0;
}

运行结果

我们知道,++作为自增运算符是有前后顺序切可以反复执行的,上面的代码只是初始版,如果写出反复执行这样就可以这样改:

test11& operator++() {
	c_rank += 1;
	return *this;
}

就可以实现以下代码

++(++(++a))

对于后++,c++规定如果在传参列表中添加int代表后++,可以添加如下代码实现后++,且后++还可以反复执行:

test11& operator++(int) {
	c_rank += 1;
	return *this;
}

那么问题来了,后++的规则是先赋值再++,那么我们添加如下代码就可以实现后++的功能:

注意的是,成员函数中的临时对象是不能引用的,所以返回值不能是test11&类型,而是test11

test11 operator++(int) {
	test11 tmp;
	tmp = *this;
	c_rank += 1;
	return tmp;
}

九、总结

1.运算符号重载 返回值 operator运算符(形参列表);
2.运算符重载可以使用全局函数,也可以用成员函数,建议用成员函数 其中 = () [] ->只可以用成员函数重载
3.运算符重载形参的顺序是一定的,要是改变运输的顺序则需要进行再次重载
4.返回值是当前对象的引用
5.关系运算符的重载,可以对自定义的类进行比较
6..对<<进行重载实现自定义类的输出,只能使用全局函数实现        
7.对new和delete进行重载时,若在类中,则作用域是类,写为全局函数,则作用域是全部

  • 24
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值