重载运算符与STL总结

时间:2023-02-04 17:33:56

                                                                                     运算符重载

1.用成员函数重载运算符

class x{

//...

返回类型 operator 运算符(形参表);

};

返回类型 X:operator 运算符(形参表)

{

     函数体;

}

例如(重载+使复数相加)
#include <iostream>

using namespace std;

class Complex//复数类   
{
public:
    //定义默认构造函数初始化数据成员
    Complex()
    {
        real = 0;
        imag = 0;
    }

    //定义初始化表初始化Complex类
    Complex(double r, double i):real(r),imag(i){}
    
    //声明成员函数,实现复数相加
    Complex complex_add(Complex &c1);   
    
    void display( );//显示复数

private:
      double real;//复数的实部
      double imag;//复数的虚部
};

//实现复数相加
Complex Complex::complex_add(Complex &c1)  //  第一个complex是指返回类型。
{  
    Complex c2;  
    
    c2.real = c1.real + real;  
    c2.imag = c1.imag + imag;  
    
    return c2;  
}  

void Complex::display( )//显示复数
{
    cout<<real<<'+'<<imag<<'i'<<endl;
}

int main( )
{
    Complex  c1(8,2), c2(7,10), c3;

    cout<<"c1 = ";
    c1.display();
    
    cout<<"c2 = ";
    c2.display();

    //执行两个复数相加
    c3 = c1.complex_add(c2);
    
    cout<<"c1 + c2 = ";
    c3.display();

  }

2.上面的operator+还可以改写的更简练一些。

Complex Complex::operator+(Complex &c2)

{   return Complex(real+c2.real,image+c2.image);}

3.注意重载运算符后,不改变其原来的功能。不改变运算符的优先级别。
4.对运算符重载的函数有两种处理方式(1)把运算符重载的函数作为类的成员函数;(2)运算符重载的函数不是类的成员函数,在类中把它声明为友元函数。
#include <iostream>

using namespace std;

class Complex//复数类   
{
public:
     Complex()
    {
        real = 0;
        imag = 0;
    }

     Complex(double r, double i):real(r),imag(i){}
    
    friend complex operator +(Complex &c1,Complex &c2);   //在类中声明友元函数。
    
    void display( );

private:
      double real;
      double imag;
};


 Complex operator +(Complex &c1,Complex &c2);    
{  
    return Complex(c1.real+c2.real,c1.image+c2.image);
}  

void Complex::display( )
{
    cout<<real<<'+'<<imag<<'i'<<endl;
}

int main( )
{
    Complex  c1(8,2), c2(7,10), c3;

    cout<<"c1 = ";
    c1.display();
    
    cout<<"c2 = ";
    c2.display();

   
    c3 = c1.complex_add(c2);
    
    cout<<"c1 + c2 = ";
    c3.display();

注意和不是友元函数的区别。
5.重载双目运算符<,在STL中经常用到。
class Time
{
	int month,day,hour,minute;
	public:
	Time(int mo,int d,int h,int mi)
	{
		month = mo,day = d,hour = h,minute = mi;

	}
	Time()
	{
		month = 1,day = 1,hour = 0,minute = 0;
	}
	friend bool operator<(Time t1,Time t2)
	{
if(t1.getMonth()==t2.getMonth())
{
    if(t1.getDay()<=t2.getDay())
    return 1;
}
else if(t1.getMonth()<=t2.getMonth())
{
    return 1;
}
return 0;
	}
这是对时间的比较。

6.重载单目运算符

例如:

#include<iostream>
 using namespace std;
 class Time
 {public:
Time(){minute=0;sec=0;}
Time(int m,int s):minute(m),sec(s){}
Time operator++();         // 声明前置自增运算符“++”重载函数
Time operator++(int);      //声明后置自增运算符“++”重载函数
void display(){cout<<minute<<":"<<sec<<endl;}
 private:
int minute;
int sec;
 };


 Time Time::operator++()      //定义前置自增运算符“++”重载函数
{
if (++sec>=60)
{
sec-=60;
++minute;
}
return *this;           //返回自加后的当前对象
}


Time Time::operator++(int)
 {
Time temp(*this);
sec++;
if (sec >= 60)
{
sec-=60;
++minute;
}
return temp;       // 返回自增前的对象
}


int main()
 {
Time time1(34,59),time2;
++time1;
time1.display();
time2 = time1 ++;
time2.display();
return 0;
7.重载输入输出运算符

friend istream&operator>>(istream&is,Time&);//先在类中声明

 istream&operator>>(istream&is,Time&date)
 {
     is>>date.month>>date.day>>date.hour>>date.minute;
     return is;
 }

friend ostream&operator<<(ostream&out,Time&);//需要先在类中声明

ostream&operator<<(ostream&out,Time&date)
{
	out<<date.month<<" "<<date.day<<" "<<date.hour<<" "<<date.minute<<" ";
	return out;
}


                                                           STL

1.vector

vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>构造函数。

用法

vector<T>c 产生空的vector.

vector<T>c1(c2) 产生同类型的才,并复制c2的所有元素。

vector<T>c(n)生成容器为n的vector。

vector<T>c(beg,end)产生一个vector以区间[beg,end]为元素初值、

~vector<T>()销毁所有元素,并释放内存。

c.size()返回元素个数。

c.empty() 判断元素是否为空。

c.max_size() 返回元素最大可能数量。

c.capacity()返回重新分配空间前可容纳的最大元素数量。

c.reserve(n)  扩大容量n。

c1==c2  判断C1是否等于c2.

c1=c2  将c2的全部元素赋值给c1.

c.assign(beg,end) 将区间[beg,end]的元素赋值给c。

c1.swap(c2)将c1和c2 元素互换。

swap(c1,c2) 同上。

at(idx) 返回索引idx所标识的元素的引用。进行越界检查

operator[](idx) 返回索引idx所标识的元素的引用。不进行越界检查

front() 返回第一个元素的引用,不检查元素是否存在。

back()返回最后一个元素的引用,不检查元素是否存在。

rbegin() 返回一个逆向迭代器,指向逆向遍历的第一个元素。

rend() 返回一个逆向迭代器,指向逆向遍历的最后一个元素。

c.insert(pos,e) 在pos位置插入元素e的副本,并返回新元素的位置。

c.insert(pos,n,e) 在pos位置n个元素e的副本。

c.insert(pos,ben,end)在pos位置插入区间[beg,end)内所有元素的副本。

c.push_back()   在尾部添加一个元素e的副本。

c.pop_back() 移除最后一个元素但不返回最后一个元素。

c.erase(pos) 删除pos元素的位置,返回下一个元素的位置

c.clear()移除所有元素,清空容器

c.resize(num)  将元素数量改为num(增加函数用defalut构造函数的产生,多余元素被删除。

c.resize(num,e) 将元素数量改为num(增加元素是e的副本)

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main(){
    vector<int> a;
    for (int i = 0; i < 5; ++i){
        a.push_back(5 - i);         //添加
    }
    cout << "Size: " << a.size() << endl;
    a.pop_back();      //移除最后一个元素。
    a[0] = 1;

    cout << "Size: " << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }
    cout << endl;

    sort(a.begin(), a.end());    //升序排列
    cout << "Size: " << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }
    cout << endl;

    a.clear();
    cout << "Size: " << a.size() << endl;
    return 0;
}

2. map/multimap

count(key)  返回键值等于key的元素个数。

find(key) 返回键值等于key的第一个元素。

lower_bound(key) 返回键值大于key的第一个元素

upper_bound(key)返回键值大于key的第一个元素。

equal_range(key)  返回键值等于key的元素区间。

下面用一个代码介绍multimap


#include <iostream>
#include <map>
#include <algorithm>
using namespace std;

int main(){
    multimap<string, int> mm1;
    multimap<string, int>::iterator mm1i, p1, p2;  //定义指针一定不能少
    mm1.insert(make_pair("b", 3));    // 用make_pair()来添加。
    mm1.insert(make_pair("a", 0));
    mm1.insert(make_pair("b", 5));
    mm1.insert(make_pair("c", 4));
    mm1.insert(make_pair("b", 2));
    cout << "Size: " << mm1.size() << endl;
    for(mm1i = mm1.begin(); mm1i != mm1.end(); mm1i++){
        cout << mm1i->first << ": " << mm1i->second << endl;
    }

    cout << "COUNT: " << mm1.count("b") << endl;
    cout << "Bound: " << endl;
    p1 = mm1.lower_bound("b");
    p2 = mm1.upper_bound("b");
    for(mm1i = p1; mm1i != p2; mm1i++){
        cout << mm1i->first << ": " << mm1i->second << endl;
    }

    return 0;
}

3.count_if 算法计算中的元素范围 [first, last) 导致返回 true,谓词的数量,并返回的谓词是真正的元素数。比count更灵活。
同理find_if 也一样。
下面给大家一个自己用STL写的程序
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<fstream>
#include<algorithm>
using namespace std;
class Time
{
	int month,day,hour,minute;
	public:
	Time(int mo,int d,int h,int mi)
	{
		month = mo,day = d,hour = h,minute = mi;

	}
	Time()
	{
		month = 1,day = 1,hour = 0,minute = 0;
	}
	friend bool operator<(Time t1,Time t2)
	{
if(t1.getMonth()==t2.getMonth())
{
    if(t1.getDay()<=t2.getDay())
    return 1;
}
else if(t1.getMonth()<=t2.getMonth())
{
    return 1;
}
return 0;
	}
	friend istream&operator>>(istream&is,Time&);
	friend ostream&operator<<(ostream&out,Time&);
	int getMonth()
	{
		return month;
	}
	int getDay()
	{
		return day;
	}
	int getHour()
	{
		return hour;
	}
	int getMinute()
	{
		return minute;
	}
	void setMonth(int d){month=d;}
	void setDay(int h){day=h;}
	void setHour(int g){hour=g;}
	void setMinute(int j){minute=j;}
};
 istream&operator>>(istream&is,Time&date)
 {
     is>>date.month>>date.day>>date.hour>>date.minute;
     return is;
 }
ostream&operator<<(ostream&out,Time&date)
{
	out<<date.month<<" "<<date.day<<" "<<date.hour<<" "<<date.minute<<" ";
	return out;
}
class Book   //      用于添加图书馆的书
{

    Time chuban;
    string shuming;
    string shuhao;
    string zuozhe;
    int ceshu;
    public:
    Book(string ming,string shuh,string zuozh,Time chuba,int cesh):chuban(chuba)
    {
        shuming=ming;
     zuozhe=zuozh;
    shuhao=shuh;
    ceshu=cesh;
    }
    Book()
    {
        zuozhe="0000";
        shuhao="0000";
        Time chu(0,0,0,0);
       chuban=chu;
       ceshu=0;
    }
    friend istream&operator>>(istream&is,Book&);
	friend ostream&operator<<(ostream&out,Book&);
	string getShuming(){return shuming;}
	string getZuozhe(){return zuozhe;}
	string getShuhao(){return shuhao;}
	Time getChuban(){return chuban;}
	int getCeshu(){return ceshu;}
};
istream&operator>>(istream&is,Book&R)
	{
	    is>>R.shuming;
	    if(R.shuming=="end")return is;
	    is>>R.shuhao>>R.zuozhe>>R.chuban>>R.ceshu;
	    return is;
	}
	ostream&operator<<(ostream&out,Book&R)
	{
		out<<R.shuming<<R.shuhao<<" "<<R.zuozhe<<" "<<R.chuban<<R.ceshu<<endl;
		return out;
	}
	class Record        //借书记录
	{
	    string zhuanye;
	    int banji;
	    string shuming;
	    string zuozhe;
	    string shuhao;
	    string xuehao;
	    Time start,end,chuban;
	    public:
	    Record(string xh,string zhuany,int banj,string shu,string shumin,string zuozh,Time chuba,Time st,Time jie):chuban(chuba),start(st),end(jie)
	    {
	        zhuanye=zhuany;
	        banji=banj;
	        shuming=shumin;
	        zuozhe=zuozh;
	        xuehao=xh;
	        shuhao=shu;
	    }
	    Record()
	    {
	        xuehao="000";
	    }
	    friend istream&operator>>(istream&is,Record&);
	friend ostream&operator<<(ostream&out,Record&);
	string getShuming(){return shuming;}
	string getZuozhe(){return zuozhe;}
	string getShuhao(){return shuhao;}
	string getXuehao(){return xuehao;}
	Time getChuban(){return chuban;}
	Time getStart(){return start;}
	Time getEnd(){return end;}
	};
istream&operator>>(istream&is,Record&R)
	{ is>>R.xuehao;
	if(R.xuehao=="end")return is;
	    is>>R.xuehao>>R.shuhao>>R.zuozhe>>R.chuban>>R.start>>R.end;
	    return is;
	}
	ostream&operator<<(ostream&out,Record&R)
	{
		out<<R.xuehao<<" "<<R.shuhao<<" "<<R.zuozhe<<" "<<R.chuban<<R.start<<R.end<<endl;
		return out;
	}
struct cmp1
{
	    string tpe;
	    cmp1(string s)
	    {
	        tpe=s;
	    }
	    bool operator()(Record &a)
	    {
	        return (a.getShuming().find(tpe)!=string::npos);
	    }
	};
class UserOp
{ public:
    vector<Book> b;
    vector<Book>::iterator it;
    multimap<string,int>b1;//书名
    multimap<string,int>::iterator mit;
    vector<Record> r;
    vector<Record>::iterator itt;
    multimap<string,int >m1;//书名
    multimap<string,int>::iterator mit1;
    multimap<string,int> m2;//书号
    multimap<string,int>::iterator mit2;
   string manager;
   public:
   UserOp(string manage):manager(manage)
   {
   }
   UserOp()
   {
       manager="0000";
   }
   friend istream&operator>>(istream&is,UserOp&u)
   {
       is>>u.manager;
   }
   friend ostream&operator<<(ostream&out,UserOp&u)
	{
        if(u.r.size()==0)
   {out<<u.manager<<" ";}
    if(u.r.size()!=0)
    {   out<<u.manager<<endl;
       for(u.itt=u.r.begin();u.itt!=u.r.end();u.itt++)
		{
		    out<<*(u.itt);
		}
		for(u.it=u.b.begin();u.it!=u.b.end();u.it++)
		{
		    out<<*(u.it);
		}
    }
    return out;
	}
	int serchbook(string s);
   void addbook();
    void addrecord();
    void serchbyshuming(string s);
    void serchbyshuhao(string s);
    void shangjia(Book h);
    void xiajia(string s);
};
void UserOp::addbook()
{
    Book s;
    int i;
    while(1)
    {
        cin>>s;
        if(s.getShuming()=="end")break;
        b.push_back(s);
        i=b.size();
        b1.insert(make_pair(s.getShuming(),i-1));
    }

}
void UserOp::addrecord()
{
    Record p;
    int i;
    while(1)
    {
        cin>>p;
        if(p.getXuehao()=="end")break;
        r.push_back(p);
       for(it=b.begin();it!=b.end();it++)
        {
            if((*it).getShuming()==p.getShuming())
            {
               (*it).getCeshu()==(*it).getCeshu()-1;
            }
        }
        i=r.size();
        m1.insert(make_pair(p.getShuming(),i-1));
        m2.insert(make_pair(p.getShuhao(),i-1));
    }
}
void UserOp::shangjia(Book h)
{
    int i;
      b.push_back(h);
       i=b.size();
        b1.insert(make_pair(h.getShuming(),i-1));
}
int UserOp::serchbook(string s)
{
    mit=b1.find(s);
    if(mit!=b1.end())
    {
        return mit->second;
    }
}
void UserOp::xiajia(string s)
{
    int i;
    i=serchbook(s);
    it=b.begin()+i;
    b.erase(it);
    b1.erase(b1.find(s));
}
void UserOp::serchbyshuming(string s)
{
	   itt=find_if(r.begin(),r.end(),cmp1(s));
	   while(itt!=r.end())
	   {
	      // it=v.begin()+mit1->second;
	       cout<<*itt;
      itt=find_if(itt+1,r.end(),cmp1(s));
	   }
	}
	int main()
	{ /*vector<Book> b;
    vector<Book>::iterator it;
    multimap<string,int>b1;//书名
    multimap<string,int>::iterator mit;
    vector<Record> r;
    vector<Record>::iterator itt;
    multimap<string,int >m1;//书名
    multimap<string,int>::iterator mit1;
    multimap<string,int> m2;//书号
    multimap<string,int>::iterator mit2;*/

      UserOp u;
      cin>>u;
      u.addbook();
      u.addrecord();
      cout<<u;


	}

最后给大家分享一下心得。

首先,运算符重载是很重要的,很有实用意义,丰富了类的功能和适用范围,重载时一般都是基于原来的功能进行延伸不能太违背原来的意思,比如

把加号重载成小于号用。重载一次一劳永逸,为下面节省很多,而且使程序更清晰。STL 使是以模板为基础的一个标准库,使c++的重要的一部分。

它非常有实用性,运用STL能使代码更简洁。我们要对STL各种容器及其特有的一些功能都要了解,用的时候也便于查找。