C++ 运算符重载

        若运算符是成员函数,左侧运算对象绑定到隐式的this指针上,所以成员运算符函数的(显式)参数数量比运算符的运算对象少一个。

        选择是否作为成员函数:
1. 必须成员:赋值= 下标[] 调用() 访问->
2. 复合赋值一般应该成员
3. 改变对象状态或与类型紧密相关的,一般应该成员,如 ++ -- 解引用*
4. 对称性运算符可能转换任意一端对象,一般非成员。

1. 输入输出运算符

class Point {
	// 以与原点之间距离排序

public:
	Point(int x = 0, int y = 0) :m_ix(x),m_iy(y) {}

	friend std::ostream& operator<<(std::ostream& os, const Point& point);
	friend std::istream& operator>>(std::istream& is, Point& point);

private:
	int m_ix;
	int m_iy;
};


/* 输出运算符
	* 形参1:非常量 ostream 引用;形参2:常量引用(欲打印类型)
	* 返回 ostream 形参
	*/
std::ostream& operator<<(std::ostream& os, const Point& point) {
	//os << "(" << point.getX() << "," << point.getY() << ")";
	os << "(" << point.m_ix << "," << point.m_iy << ")";
	return os;
}


/*
*  输入运算符必须处理可能的输入失败的情况
*/
std::istream& operator>>(std::istream& is, Point& point) {
	is >> point.m_ix >> point.m_iy;
	if (!is) {
		point.m_ix = -1;
		point.m_iy = -1;
	}
	return is;
}


int main()
{
	Point A(1, 2), B(2, 3);
	std::cout << A << B << std::endl;

	Point C(0,0);
	std::cin >> C;
	std::cout << C << std::endl;

    return 0;
}

2. (复合)赋值运算符


class Point {
	// 以与原点之间距离排序

public:
	Point(int x = 0, int y = 0) :m_ix(x),m_iy(y) {}

	//赋值运算符
	Point& operator=(const Point& point);

	//复合赋值运算符
	Point& operator+=(const Point& point);
	Point& operator-=(const Point& point);

private:
	int m_ix;
	int m_iy;
};

Point& Point::operator=(const Point& point) {
	m_ix = point.m_ix;
	m_iy = point.m_iy;
	return *this;
}

Point& Point::operator+=(const Point& point) {
	m_ix += point.m_ix;
	m_iy += point.m_iy;
	return *this;
}

Point& Point::operator-=(const Point& point) {
	m_ix -= point.m_ix;
	m_iy -= point.m_iy;
	return *this;
}

int main()
{

    return 0;
}

3. 前置/后置 递增递减运算符

class Point {
	// 以与原点之间距离排序

public:
	Point(int x = 0, int y = 0) :m_ix(x),m_iy(y) {}

	Point& operator++();
	Point& operator--();

	Point operator++(int); // 后置
	Point operator--(int);

private:
	int m_ix;
	int m_iy;
};


Point& Point::operator++() {
	++m_ix;
	++m_iy;
	return *this;
}

Point& Point::operator--() {
	--m_ix;
	--m_iy;
	return *this;
}

Point Point::operator++(int)
{
	Point tmp = *this;
	++* this;
	return tmp;
}

Point Point::operator--(int)
{
	Point tmp = *this;
	--* this;
	return tmp;
}

int main()
{
    Point A(1, 2);
	
    std::cout << A << std::endl;//1,2

	++A;
	std::cout << A << std::endl;//2,3
	--A;
	std::cout << A << std::endl;//1,2
	std::cout << A++ << std::endl;//2,3 -> 1,2
	std::cout << A-- << std::endl;//1,2 -> 2,3
    
    return 0;
}

4. 算术运算符

Point operator+(const Point& lhs, const Point& rhs) {
	Point ptemp = lhs;
	ptemp += rhs;
	return ptemp;
}

int main()
{
    Point A(0,0),B(1,2),C(2,3);
    A = B + C;
    return 0;
}

5. 关系运算符

class Point {
	// 以与原点之间距离排序

public:
	Point(int x = 0, int y = 0) :m_ix(x),m_iy(y) {}

	int getX()const { return m_ix; }
	int getY()const { return m_iy; }
	int distance()const {
		return m_ix * m_ix + m_iy * m_iy;
	}


	bool operator<(const Point& point);


private:
	int m_ix;
	int m_iy;
};

bool operator==(const  Point& lhs, const Point& rhs) {
	return lhs.getX() == rhs.getX()
		&& lhs.getY() == rhs.getY();
}

bool operator!=(const  Point& lhs, const Point& rhs) {
	return !(lhs == rhs);
}

bool Point::operator<(const Point& point) {
	if (distance() < point.distance()) {
		return true;
	}
	return false;
}

6. 函数调用运算符

        普通函数的无状态特点。

        重载了函数调用运算符,该类 对象 可作为一个函数使用。即函数对象。

        操作数个数是不固定的。

返回类型 类名::operator()(参数列表)
{
    // ... 
}
#include <iostream>

class FunctionClass
{
public:
	FunctionClass(int icalls = 0) :m_iCall(icalls) {}

	void operator()(int x) {
		++m_iCall;
		std::cout << "(" << x << ")" << std::endl;
		std::cout << m_iCall << " calls" << std::endl;
	}
	void operator()(int x,int y) {
		++m_iCall;
		std::cout << "(" << x << "," << y << ")" << std::endl;
		std::cout << m_iCall << " calls" << std::endl;
	}

private:
	int m_iCall;
};

int main()
{
	FunctionClass fo;
	fo(1);
	fo(1, 2);

	return 0;
}

7. 下标访问运算符

arr[idx] 解释为 arr.operator[](idx)

返回类型 &类名::operator[](参数类型);
返回类型 &类名::operator[](参数类型) const;
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>

class mystr
{
public:
	mystr(std::size_t size = 10)
		: m_iSize(size)
		, m_pChar(new char[m_iSize]())
	{
	}

	friend std::ostream& operator<<(std::ostream& os, const mystr& str);

	mystr& operator=(const std::string& str) {
		std::cout << "mystr& operator=" << std::endl;

		m_iSize = str.size() + 1;
		delete[] m_pChar;
		m_pChar = new char[m_iSize]();
		strcpy(m_pChar, str.c_str());

		return *this;
	}

	char& operator[](std::size_t idx)
	{
		if (idx < m_iSize)
		{
			return m_pChar[idx];
		}
		else
		{
			static char nullchar = '\0';
			return nullchar;
		}
	}
	const char& operator[](std::size_t idx) const//针对的是const对象
	{
		if (idx < m_iSize)
		{
			return m_pChar[idx];
		}
		else
		{
			static char nullchar = '\0';
			return nullchar;
		}
	}
	~mystr()
	{
		delete[] m_pChar;
		m_pChar = nullptr;
	}

private:
	std::size_t m_iSize;
	char* m_pChar;
};

std::ostream& operator<<(std::ostream& os, const mystr& str)
{
	os << str.m_iSize << "long; " << str.m_pChar;
	return os;
}

int main()
{
	const std::string str("hello");
	
	mystr obj;
	obj = str;

	std::cout << obj << std::endl;
	std::cout << "obj[1]: " << obj[1] << std::endl;

	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值