C++ 基础(4) 运算符重载

一. 概述

C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其新的功能,以满足自身的需求。

运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够用同名的函数来完成不同的基本操作。要重载运算符,需要使用被称为运算符函数的特殊函数形式,运算符函数形式:operatorp() 后面的p为要重载的运算符符号

<返回类型说明符> operator <运算符符号>(<参数表>)
{
    
    
     <函数体>
}

1.1 为什么使用操作符重载?

对于系统的所有操作符,一般情况下,只支持基本数据类型和标准库中提供的class,对于用户自己定义class,如果想支持基本操作,比如比较大小,判断是否相等,等等,则需要用户自己来定义关于这个操作符的具体实现

比如,判断两个人是否一样大,我们默认的规则是按照其年龄来比较,所以,在设计person 这个类的时候,我们需要考虑重载操作符==,而且,根据刚才的分析,比较的依据应该是age或者身高其他属性

那么为什么叫重载呢?这是因为,在编译器实现的时候,已经为我们提供了这个操作符的基本数据类型实现版本,但是现在他的操作数变成了用户定义的数据类型class,所以,需要用户自己来提供该参数版本的实现

1.2 C++哪些运算符允许重载

C++中绝大部分运算符都是可以被重载的

不能重载的运算符只有5个:

  1. . 成员访问运算符
  2. * 成员指针访问运算符
  3. :: 域运算符
  4. sizeof 长度运算符
  5. ?: 条件运算符

1.3 重载运算符的限制

  1. 只有C++预定义的操作符才可以被重载
  2. 对于内置类型的操作符,它的预定义不能改变,即不能改变操作符原来的功能
  3. 重载操作符不能改变他们的操作符优先级
    例如”*“和”/“优先级高于”+“和”-“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法强制改变重载运算符的运算顺序
  4. 重载操作符不能改变操作数的个数
    如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两个参数。运算符”+“,”-“,”*“,”&“等既可以作为单目运算符,也可以作为双目运算符,可以分别将它们重载为单目运算符或双目运算符。
  5. 重载运算符的函数不能有默认的参数
    否则就改变了运算符参数的个数,与前面第4点矛盾。
  6. 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)
    也就是说,参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据成员的运算符的性质,如下面这样是不对的:
int operator + (int a,int b)
{
    
    
        return(a-b);
}

二. 使用重载运算符

2.1 重载 自定义对象的 + 运算符

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	Person operator + (Person &p)
	{
    
    
		Person res;
		res.name = this->name + p.name + "的共资产";
		res.age = (this->age + p.age) / 2;
		res.account = this->account + p.account;
		return res;
	}
};
int main()
{
    
    
	Person p1("haiyang1",21,20000);
	Person p2("haiyang2", 21, -2000);
	// Person p3 = p1.operator+(p2);
	Person p3 = p1 + p2;
	cout << p3.name << "\n" << p3.account << "\n" << p3.age << endl;
	return 0;
}

2.2 重载<<运算符

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
};
// << 只能全局重载
ostream& operator<< (ostream& cout,Person &p)
{
    
    
	cout << "name = " << p.name << "age = " << p.age << "account = " << p.account << endl;
	return cout;
}

int main()
{
    
    
	Person p1("haiyang1",21,20000);
	Person p2("haiyang2", 21, -2000);

	cout << p1 << p2 <<endl;
	return 0;
}

2.3 重载 ++i运算符

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	// 年龄自增
	Person& operator++ ()
	{
    
    
		this->age++;
		return *this;
	}
};
int main()
{
    
    
	Person p1("haiyang1",21,20000);
	cout << (++p1).age << endl; // 22
	return 0;
}

2.3 重载 i++运算符

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	// ++i
	Person& operator++ ()
	{
    
    
		this->age++;
		return *this;
	}
	// i++
	Person operator++ (int)
	{
    
    
		Person p = *this;
		this->age++;
		return p;
	}

};
int main()
{
    
    
	Person p1("haiyang1",21,20000);
	cout << (p1++).age << endl; // 21
	cout << (p1++).age << endl; // 22
	return 0;
}

2.4 重载 =运算符

class Person
{
    
    
public:
	string name;
	int * age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int *age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	void operator= (Person & p)
	{
    
    
		if (NULL != this->age) 
		{
    
    
			delete this->age;
			this->age = NULL;
		}
		this->name = p.name;
		this->account = p.account;
		this->age = new int(*p.age);
	}
};
int main()
{
    
    
	Person p1("haiyang1",new int(21),20000);
	Person p2 = p1;
	return 0;
}

2.4 重载 ==运算符

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	bool operator== (Person & p)
	{
    
    
		return this->name == p.name && this->age == p.age && this->account == p.account;
	}
};
int main()
{
    
    
	Person p1("haiyang1", 21,20000);
	Person p2("haiyang1", 21, 20000);
	cout << (p1 == p2) << endl; // 1
	return 0;
}

2.5 重载 () 函数调用运算符

仿函数

class Person
{
    
    
public:
	string name;
	int age;
	int account;
	Person() 
	{
    
    
	}
	Person(string name,int age,int account)
	{
    
    
		this->name = name;
		this->age = age;
		this->account = account;
	}
	void operator() (string text)
	{
    
    
		cout << text << endl;
	}
};
int main()
{
    
    
	Person p1("haiyang1", 21,20000);
	p1("haiyang1的账户信息");
	Person()("haiyang2的账户信息"); // 匿名函数对象调用仿函数
	return 0;
}

猜你喜欢

转载自blog.csdn.net/haiyanghan/article/details/112797757
今日推荐