c++操作符重载
操作符重载对于我们自定义的类或者结构体等非基础数据类型是非常重要和常见的,否则,我们则需要繁琐的拆解数据进行基础操作。比如==,++,<>等。最近有部分童鞋们在学习容器时遇到find函数报错,问的多,所以写出来以供参考。
文章目录
一、操作符重载的规则
操作符重载的基本规则如下:
1.不能创建新的操作符,只能重载已有的操作符。
2.不能改变操作符的优先级和结合性。
3.不能改变操作数的个数,比如一元操作符只能重载为一元操作符,二元操作符只能重载为二元操作符。
4.以下操作符不能被重载:
::(域解析操作符)
.*(成员指针访问操作符)
.(成员访问操作符)
?:(条件操作符)
sizeof(对象大小操作符)
typeid(类型信息操作符)
5.重载操作符必须至少有一个操作数是用户定义的类型。
6.重载操作符可以是成员函数或非成员函数(友元函数)
二、常见操作符重载举例
1、操作符重载的语法规则
对于操作符的重载函数,都必须以关键operator加上操作符作为函数名,形如:
返回类型 operator 操作符号 (const ClassA t){
return ~~
}
2、重载等号=和<小于号
代码中,我们考虑实现简单,就使用一个teacher的结构体来作为重载的自定义数据类型,代码如下:
struct teacher{
string name;
int age;
teacher& operator=(teacher& t)
{
age=t.age;
name=t.name;
return *this;
}
//下面的重载直接用来比较年龄了
bool operator < (const teacher t){
return age < t.age;
}
}
3、操作符+的重载
以下代码,完整的展示了一个类中的+号的重载,当然,对于这个类中所设计的姓名和年龄粗暴的相加这个不符合我们的生活显示,但这里我们主要是为清晰的展示其过程。
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
#include <iostream>
using namespace std;
class Student
{
public:
string name;
int age;
void print();
void print(int a);
Student();
Student(string name_ ,int age_);
Student * operator +(Student &t1);
protected:
};
#endif
#include "Student.h"
Student::Student()
{
}
Student::Student(string name_ ,int age_)
{
name=name_;
age=age_;
}
void Student::print()
{
cout<<name<<"--"<<age<<endl;
}
void Student::print(int a)
{
cout<<name<<"--"<<age+a<<endl;
}
Student* Student::operator +(Student &t1)
{
Student *st;
st->name=name+t1.name;
st->age=age+t1.age;
return st;
}
4、重载cout
cout和cin的原理和实现基本一样,所以这里只拿cout进行举例。cout和cin对应的操作符分别是<< 或者 >> 运算符。他们必须使用istream 或者 ostream两个类。但是,这两个是没有拷贝构造函数的(应该说是私有拷贝构造函数),所以它们只能返回一个引用。当然,其他有拷贝构造函数的也可以不用引用,不过那样需要拷贝来拷贝去,性能大打折扣,所以大多都是传递引用,直接对源对象进行更改,当然,只读的可以加上const 引用。
a、通过友元函数
friend ostream & operator<<(ostream &out, const teacher &t);
};
ostream & operator<<(ostream &out,const teacher &t )
{
return out <<t. name << " " << t.age << " " << t.cellphone << " ";
}
b、通过非有源函数,成员函数实现
直接放在结构体外或者是类外即可调用成功,只不过代码都丢在外码不是很好看,维护的时候不太方便。
ostream & operator<<(ostream &out,const teacher &t)
{
return out << t.name << " " << t.age << " " << t.cellphone << " ";
}
5、利用重载==来实现find的正确调用
在容器中调用find我们常常会遇到报错,特别我们在vector或者list中是很容易遇到的。解决的方案就是为我们的自定义类或者结构体实现==号的符号重载。
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
struct teacher {
string name;
int age;
operator int()
{
return this->age;
}
bool operator ==(const teacher &t)const
{
if (name == t.name)
return 1;
else
return 0;
}
};
list<teacher> teas;
int main(int argc, char** argv) {
teacher t1{ "haijiao",48 };
teacher t2{ "hai",50 };
teacher t3{ "liuxin",20 };
teacher t4{ "xudai",14 };
teacher t5{ "dai",30 };
teas.push_back(t1);
teas.push_back(t2);
teas.push_back(t3);
teas.push_back(t4);
teas.push_back(t5);
teacher t{ "hai",0 };
list<teacher>::iterator tp = find(teas.begin(), teas.end(), t);
teas.insert(tp, t);
for (list<teacher>::iterator ta = teas.begin(); ta != teas.end(); ta++)
cout << ta->name << "-" << ta->age << endl;
return 0;
}
三、注意和说明
当重载为成员函数时,第一个操作数隐式传递为 this 指针。
当重载为非成员函数时,通常需要将该函数声明为类的友元,以便能够访问类的私有和保护成员。
对于某些操作符,如 +=、-= 等,通常需要同时重载它们和它们对应的二元操作符,以保持一致的行为。
更多推荐
所有评论(0)