C++重载运算符operator

本文详细介绍了C++中运算符重载的概念与实现方式,包括前自加、后自加、加减运算符及赋值运算符的重载,并展示了如何避免浅复制带来的问题。

重载运算符用operator关键字,后面跟上要操作的运算符,比如operator++(重载前自加),要把operator++看成是一个整体,它就是函数的名字,前面的返回类型和后面的形参表和普通函数一样。

1、重载前自加

class MyClass
{
public:
	MyClass(){n = 0;}
	void operator++()//operator++是一个整体,看做函数的名字,函数的返回值是void
	{
		++n;
	}
	int get()const{return n;}
private:
	int n;
};
int main()
{
	MyClass M;
	++M;//前自加
	cout<<M.get()<<endl;//--1
	return 0;
}

2、将自加后的对象赋给另一个对象
class MyClass
{
public:
	MyClass(){n = 0;}
	MyClass(const MyClass &m)
	{
		n = m.n;
	}
	//前自加
	const MyClass &operator++()
	{
		//自加之后返回这个对象
		++n;
		return *this;
	}
	int get()const{return n;}
private:
	int n;
};
int main()
{
	MyClass M;
	//把自加后的M赋值给mc
	MyClass mc = ++M;//++M相当于M.operator++()
	cout<<mc.get()<<endl;//--1
	return 0;
}

3、重载后自加
前自加是先将对象的成员+1之后再返回对象,后自己是先返回对象,再将对象的成员+1
前自减和后自减同前后自加一样
class MyClass
{
public:
	MyClass(){n = 0;}
	MyClass(const MyClass &m)
	{
		n = m.n;
	}

	//后自加
	//int是一个无效参数,不用理会,但是必须有且必须为int类型,在这里只是作为一个标识,表明重载的是后自加
	const MyClass operator++(int)
	{
		//先记住对象调用后自加之前的状态
		MyClass m(*this);
		++n;//或++*this
		return m;
	}

	int get()const{return n;}
private:
	int n;
};
int main()
{
	MyClass M;
	MyClass C = M++;
	cout<<C.get()<<endl;//--0
	return 0;
}


4、重载+-运算符

class MyClass
{
public:
	MyClass(){n = 0;}
	MyClass(int i){n = i;}
	MyClass(const MyClass &m)
	{
		n = m.n;
	}

	//重载+号运算符
	MyClass operator+(const MyClass &t)
	{
		//n是+号左边对象成员
		//t是+号右边对象
		return MyClass(n + t.n);
	}

	//重载-号运算符
	MyClass operator-(const MyClass &t)
	{
		return MyClass(n - t.n);
	}

private:
	int n;
};
int main()
{
	MyClass m1(1),m2(2);
	MyClass m3 = m1 + m2;//m1.operator+(m2);
	MyClass m4 = m3 - m1;//m3.operator-(m1);
	return 0;
}

5、重载=赋值运算符
由于默认复制构造函数是浅层复制,所以当成员变量中含有指针的时候,如果还是利用浅层复制,比如a=b,此时对象a和对象b中的指针成员拥有相同的内存地址,删除任意一个对象都会造成另一个对象中的指针成员成为野指针,最终导致程序崩溃,所以重载=运算符的时候,需要显式的定义自己的复制构造函数,相应的构造函数和析构函数也要做对应的修改。
class MyClass
{
public:
	MyClass()
	{
		p = new int; *p=1;
	}
	MyClass(int i)
	{
		p = new int; *p=i;
	}
	MyClass(const MyClass &m)
	{
		p = new int; *p = *(m.p);
	}
	~MyClass()
	{
		if(p)
		{
			delete p;
			p = NULL;
		}
	}

	const MyClass &operator=(const MyClass &m)//m是=号右边的对象
	{
		//自己给自己赋值的情况
		if (this == &m)
		{
			return *this;
		}
		else
		{
			//把=号右边对象成员的值赋给左边对象成员
			*p = *(m.p);
			return *this;
		}
	}
private:
	int *p;
};
int main()
{
	MyClass *p = new MyClass(100);
	MyClass m(200);
	m = *p;//相当于m.operator=(*p);
	delete p;
	p = NULL;
	return 0;
}


C++优先队列是一种特殊的队列,能根据元素的优先级决定元素的出队顺序,每次出队的都是优先级最高的元素,可通过重载运算符 `operator` 来定制优先级 [^1]。 ### 重载 `operator<` 来定制优先级 在优先队列中,默认情况下使用 `operator<` 来比较元素,以确定元素的优先级。可以通过重载 `operator<` 来实现自定义的优先级比较逻辑。比如,在基于优先级和时间戳排序的场景中,如果要优先处理优先级数值小的任务,且当优先级相同时优先处理时间戳较早的任务,可按如下方式实现: ```cpp #include <iostream> #include <queue> #include <vector> struct Task { int priority; int timestamp; Task(int p, int t) : priority(p), timestamp(t) {} // 重载 operator< bool operator<(const Task& other) const { if (this->priority == other.priority) return this->timestamp > other.timestamp; // 优先处理时间戳较早的任务 return this->priority > other.priority; // 优先级数值小的任务被视为优先级高 } }; int main() { std::priority_queue<Task> pq; pq.push(Task(2, 1)); pq.push(Task(1, 2)); pq.push(Task(2, 0)); while (!pq.empty()) { Task task = pq.top(); pq.pop(); std::cout << "Priority: " << task.priority << ", Timestamp: " << task.timestamp << std::endl; } return 0; } ``` 在上述代码中,定义了 `Task` 结构体,并重载了 `operator<`。在 `main` 函数里创建了一个优先队列 `pq`,往队列中添加了几个 `Task` 对象,然后按优先级顺序依次输出队列中的元素。 ### 重载 `operator->` 以下是一个展示 `operator->` 重载的示例,该示例说明了三种不同的使用 `operator->` 运算符重载的方法: ```cpp #include <iostream> class Wrapper { public: Wrapper(int value) : m_value(value) {} // 重载 -> 运算符 Wrapper* operator->() { std::cout << "operator-> called" << std::endl; return this; } void print() const { std::cout << "Value: " << m_value << std::endl; } private: int m_value; }; int main() { // 方法 1:直接使用对象实例调用 Wrapper obj(42); obj->print(); // 输出:operator-> called \n Value: 42 // 方法 2:通过引用调用 Wrapper& ref = obj; ref->print(); // 输出:operator-> called \n Value: 42 // 方法 3:通过指针调用 Wrapper* ptr = &obj; ptr->print(); // 直接调用类成员方法,不会触发 operator-> 重载 // 通过指针先解引用,再调用重载的 -> 运算符 (*ptr)->print(); // 输出:operator-> called \n Value: 42 return 0; } ``` 此代码定义了 `Wrapper` 类,重载了 `operator->` 运算符。在 `main` 函数中,通过不同方式调用 `operator->` 重载,展示了其不同的调用效果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯洁码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值