运算符重载与STL学习总结


【运算符重载】

1.引入:运算符重载使得用户自定义的数据以一种更简洁的方式工作。

2.运算符重载规则

1)限制:

<不能重载的运算符>  .       ::   .*  ?:    sizeof

<可以重载的运算符>  +     -     *     /     %   ^    &    |     ~

!  =    <    >    += -=  *=  /=  %

^=     &= |=  << >> >>=     <<=     == !=

<=     >= && ||  ++ --    ->*       ‘      ->

[]       ()    new      delete  new[]     delete[]

重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:

Ø  不改变运算符的优先级

Ø  不改变运算符的结合性

Ø  不改变运算符所需要的操作数

Ø  不能创建新的运算符

3.用成员函数或友元函数重载运算符

1)一元运算符

        Object opop Object

  重载为成员函数,解释为:

Object .operator op ()

操作数由对象Object通过this指针隐含传递

重载为友元函数,解释为:

operatorop (Object)

        操作数由参数表的参数Object提供

  2)二元运算符

ObjectL   op  ObjectR

重载为成员函数,解释为:

ObjectL . operator op (ObjectR )

左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递

重载为友元函数,解释为:

operatorop ( ObjectL, ObjectR )

左右操作数都由参数传递

3)用成员函数重载运算符

 成员运算符函数的原型在类的内部声明格式如下:

class X

 {

     //…

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

    //…

}

在类外定义成员运算符函数的格式如下:

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

{

     函数体

}

双目运算符重载为成员函数:

对双目运算符而言,成员运算符函数的形参表中仅有一个参数,它作为运算符的右操作数,此时当前对象作为运算符的左操作数,它是通过this指针隐含地传递给函数的。

例:对复数的重载

#include <iostream.h>
class Complex
{
public:
	Complex( )	{real=0,imag=0;}
	Complex(double r,double i)	{real=r; imag=i;}
	 Complex operator + (Complex &c2); 
	void display( );
private:
	   double real;
	   double imag;
}; 
Complex Complex:: operator + (Complex &c2) 
{
	return Complex(real+c2.real, imag+c2.imag);
}
void Complex::display( )
{
	cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
int main( )
{
	Complex c1(3,4),c2(5,-10),c3;
	c3=c1+c2;
	cout<<"c1=";c1.display( );
	cout<<"c2=";c2.display( );
	cout<<"c1+c2 =";	c3.display( );
	return 0;
}

注:一般而言,如果在类X中采用成员函数重载双目运算符@,成员运算符函数operator@ 所需的一个操作数由对象aa通过this指针隐含地传递,它的另一个操作数bb在参数表中显示,aabb是类X的两个对象,则以下两种函数调用方法是等价的:

    aa @ bb;                      // 隐式调用

    aa.operator @(bb);     // 显式调用

单目运算符重载为成员函数:

 对单目运算符而言,成员运算符函数的参数表中没有参数,此时当前对象作为运算符的一个操作数。

一般而言,采用成员函数重载单目运算符时,以下两种方法是等价的:

@aa;                      // 隐式调用

  aa.operator@();    // 显式调用

成员运算符函数operator @所需的一个操作数由对象aa通过this指针隐含地传递。因此,在它的参数表中没有参数。

4)用友元函数重载

Ø  友元函数重载运算符常用于运算符的左右操作数类型不同的情况:
在第一个参数需要隐式转换的情形下,使用友元函数重载

           运算符是正确的选择

Ø   友元函数没有 this 指针,所需操作数都必须在参数表显式

           声明,很容易实现类型的隐式转换

Ø   C++中不能用友元函数重载的运算符有

      =    ()    []    >

例:复数运算


#include<iostream>
using namespace std;
class Complex
{ 
public:
      Complex( double r =0, double i =0 ) { Real = r ;   Image = i ; }
      Complex(int a) { Real = a ;  Image = 0 ; } 
      void print() const ;
   friend Complex operator+ ( const Complex & c1, const Complex & c2 ) ;
   friend Complex operator- ( const Complex & c1, const Complex & c2 ) ;
   friend Complex operator- ( const Complex & c ) ;
  private:  
      double  Real, Image ;
};
Complex operator + ( const Complex & c1, const Complex & c2 )
  { 
double r = c1.Real + c2.Real ;  double i = c1.Image+c2.Image ;
     return Complex ( r,  i ) ;
  }
Complex operator - ( const Complex & c1, const Complex & c2 )
  { double r = c1.Real - c2.Real ;  double i = c1.Image - c2.Image ;
     return Complex ( r,  i ) ;
  }
Complex operator- ( const Complex & c )
  { return Complex ( -c.Real, - c.Image ) ; }
void Complex :: print() const
  { 
cout << '(' << Real << " , " << Image << ')' << endl ; 
}


5)成员运算符函数与友元运算符函数的比较

①成员运算符函数比友元运算符函数少带一个参数(后置的++--需要增加一个形参)。

 ②双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。

4.几个典型运算符重载

数学类中常用的几个运算符重载的特点和应用

  A  Aobject

运算符 ++ - - 有两种方式:

前置方式:        ++Aobject  --Aobject

成员函数  重载  A :: Aoperator++ () ; 

      解释为:       Aobject. operator ++( ) ;

    友元函数 重载  friend A operator++ (A &) ;

      解释为:      operator++( Aobject ) ;          

后置方式:  Aobject ++      Aobject --

成员函数  重载  A ::A  operator++ (int) ;

      解释为:      Aobject. operator ++( 0 ) ;

    友元函数 重载:     friend A operator++ (A &, int) ;  

      解释为:      operator++(Aobject,0)

例:成员函数重载++

#include<iostream>
using namespace std;
class  Increase
{ public :
     Increase ( ) { value=0; }
     void  display( )  const { cout<<value<<'\n'; } ;
     Increase  operator ++ ( ) ; 	     // 前置 
     Increase  operator ++ ( int ) ; 	     // 后置 
   private:   unsigned  value ;
};
Increase  Increase :: operator ++ ( ) 	 
  { value ++ ;   return *this ; }	
Increase  Increase :: operator ++ ( int )	 
 { Increase  temp;   temp.value = value ++ ;   return  temp; }
int main( )
  { 
Increase   a ,  b , n ;    
int  i ;
     for ( i = 0 ; i < 10 ; i ++ ) 
 a = n ++ ;
     cout <<"n= " ;
  n.display( ) ;   
cout <<"a= " ;  
a.display( ) ;
     for ( i = 0 ; i < 10 ; i ++ ) 
 b = ++ n ;
     cout << "n= " ;  
 n.display( ) ;   
cout << "b= " ;   
b.display( ) ;
 }


例:友元函数重载++

#include<iostream>
using namespace std;
class  Increase
{ public :
     Increase ( ) { value=0; }
     void  display( )  const { cout<<value<<'\n'; } ;
     friend Increase  operator ++ ( Increase & ) ; 	 // 前置	
     friend Increase  operator ++ ( Increase &, int ) ;	 // 后置 
  private:   unsigned  value ;
};
Increase  operator ++ ( Increase & a )
  { a.value ++ ;   return a ; }	
Increase  operator ++ ( Increase & a, int )
 { 
Increase  temp(a);  
 a.value ++ ;   
return  temp;
 }
int main( )
  {
 Increase   a ,  b , n ;   
 int  i ;
     for ( i = 0 ; i < 10 ; i ++ )  
a = n ++ ;
     cout <<"n= " ; 
  n.display( ) ;   
cout <<"a= " ;   
a.display( ) ;
     for ( i = 0 ; i < 10 ; i ++ )  
b = ++ n ;
     cout << "n= " ;   
n.display( ) ;  
 cout << "b= " ;  
 b.display( ) ;
 }

5.重载赋值运算符

Ø 赋值运算符重载用于对象数据的复制

Ø  operator= 必须重载为成员函数

Ø 重载函数原型为:

    类名 &  类名  ::operator= ( 类名 ) ;

例:定义name类的重载赋值函数


 #include<iostream>
#include<cstring>
using namespace std;
class  Name
{
 public :
     Name ( char  *pN ) ;
     Name( const Name & ) ;		    //复制构造函数 
     Name& operator=( const Name& ) ;     // 重载赋值运算符
     ~ Name() ;
   protected : 
     char  *pName ;
     int size ;
} ;
int main()
{
 Name Obj1( "ZhangSan" ) ;
   Name Obj2 = Obj1 ;		// 调用复制构造函数 
   Name Obj3( "NoName" ) ;
   Obj3 = Obj2 = Obj1 ;		// 调用重载赋值运算符函数 
}
Name::Name ( char  *pN )
 { cout <<" Constructing " << pN << endl ;
    pName = new char[ strlen( pN ) + 1 ] ;
    if( pName != 0 ) strcpy( pName,pN ) ;
    size = strlen( pN ) ;
 }
Name::Name( const Name & Obj )	 //复制构造函数 
{ 
cout << " Copying " << Obj.pName << " into its own block\n";
   pName = new char[strlen( Obj.pName ) + 1 ] ;
   if ( pName != 0 ) strcpy( pName, Obj.pName ) ;
   size = Obj.size;
}
Name & Name::operator= ( const Name & Obj )	 // 重载赋值运算符 
{ 
delete  []pName ;
   pName = new char[ strlen( Obj.pName ) + 1 ] ;
   if ( pName != 0 ) strcpy( pName , Obj.pName ) ;
   size = Obj.size ;
   return *this ;
}
Name::~ Name()
{
 cout << " Destructing " << pName << endl ;
   delete  []pName ;
}


6.重载运算符[]()

Ø  运算符 [] () 是二元运算符

Ø   [] () 只能用成员函数重载,不能用友元函数重载

1)重载下标运算符[]

[] 运算符用于访问数据对象的元素

重载格式     类型  ::operator[]  ( 类型 )

例:

      x 是类 X 的一个对象,则表达式

           x[ y ]

        可被解释为

           x. operator [ ] ( y )

2)重载函数调用符 ()

() 运算符用于函数调用

重载格式     类型  ::operator()  ( 参数表  )

      x 是类 X 的一个对象,则表达式

           x( arg1, arg2, )

      可被解释为

           x. operator () (arg1, arg2, )

7.重载流插入和流提取运算符

Ø  istream ostream C++ 的预定义流类

Ø  cin istream 的对象,cout ostream 的对象

Ø  运算符 << ostream 重载为插入操作,用于输出基本类型数据

Ø  运算符 >> istream 重载为提取操作,用于输入基本类型数据

Ø  用友元函数重载 << >> ,输出和输入用户自定义的数据类型

重载输出运算符“<<”(只能被重载成友元函数,不能重载成成员函数)

定义输出运算符“<<”重载函数的一般格式如下:

    ostream& operator<<(ostream&outclass_name&obj)

    {

          out<<obj.item1;

          out<<obj.item2;

          .. .

          out<<obj.itemn;

          return out;

    }

重载输入运算符“>>” (只能被重载成友元函数)

定义输入运算符函数“>>”重载函数的一般格式如下:

    istream& operator>>(istream&inclass_name&obj)

    {

            in>>obj.item1;

            in>>obj.item2;

            . . .

            in>>obj.itemn;

            return in;

    }

例:

#include<iostream>
#include<cstdlib>
using namespace std;
class vector
{ public :
     vector( int size =1 ) ;       ~vector() ;
     int & operator[] ( int i ) ;
     friend ostream & operator << ( ostream & output , vector & ) ;
     friend istream & operator >> ( istream & input, vector & ) ;
     private :  
     int * v ;     int len ;
};
int main()
{
   int k ;    cout << "Input the length of vector A :\n" ;     cin >> k ;
   vector A( k ) ;    cout << "Input the elements of vector A :\n" ;    
   cin >> A ;          cout << "Output the elements of vector A :\n" ;
   cout << A ;
}


【标准模板库STL

1.STL组件

容器(Container)-管理某类对象的集合

迭代器(Iterator)-在对象集合上进行遍历

算法(Algorithm)-处理集合内的元素

容器适配器(container adaptor

函数对象(functor)

2.STL容器的共同操作

(1)初始化(initialization

产生一个空容器

std::list<int> l;

以另一个容器元素为初值完成初始化

std::list<int> l;

std::vector<float>c(l.begin(),l.end());

以数组元素为初值完成初始化

int array[]={2,4,6,1345};

std::set<int>c(array,array+sizeof(array)/sizeof(array[0]));

(2)与大小相关的操作(size operator

size()-返回当前容器的元素数量

empty()-判断容器是否为空

max_size()-返回容器能容纳的最大元素数量

(3)比较(comparison

==,!=,<,<=,>,>=

比较操作两端的容器必须属于同一类型

如果两个容器内的所有元素按序相等,那么这两个容器相等

采用字典式顺序判断某个容器是否小于另一个容器

4)赋值和交换

swap用于提高赋值操作效率

5)与迭代器相关的操作

begin()-返回一个迭代器,指向第一个元素

end()-返回一个迭代器,指向最后一个元素之后

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

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

6)元素操作

insert(pos,e)-将元素e的拷贝安插于迭代器pos所指的位置

erase(beg,end)-移除[begend]区间内的所有元素

clear()-移除所有元素

3.迭代器(iterator

可遍历STL容器内全部或部分元素的对象

指出容器中的一个特定位置

迭代器的基本操作:

操作

效果

*

返回当前位置上的元素值。如果该元素有成员,可以通过迭代器以operator ->取用

 

++

将迭代器前进至下一元素

 

==和!=

判断两个迭代器是否指向同一位置

为迭代器赋值(将所指元素的位置赋值过去)

 

=

 

所有容器都提供获得迭代器的函数

操作

效果

begin()

返回一个迭代器,指向第一个元素

end()

返回一个迭代器,指向最后一个元素之后

 

半开区间[beg, end)的好处:

1)为遍历元素时循环的结束时机提供了简单的判断依据(只要未到达end(),循环就可以继续)

2)不必对空区间采取特殊处理(空区间的begin()就等于end()

所有容器都提供两种迭代器

container::iterator/模式遍历元素

container::const_iterator只读模式遍历元素

迭代器示例:iterator

<迭代器分类>

双向迭代器

①可以双向行进,以递增运算前进或以递减运算后退、可以用==!=比较。

listsetmap提供双向迭代器

随机存取迭代器

①除了具备双向迭代器的所有属性,还具备随机访问能力。

②可以对迭代器增加或减少一个偏移量、处理迭代器之间的距离或者使用<>之类的关系运算符比较两个迭代器。

vectordequestring提供随机存取迭代器

4.vector

Ø  vector模拟动态数组

Ø  vector的元素可以是任意类型T,但必须具备赋值和拷贝能力(具有public拷贝构造函数和重载的赋值操作符)

Ø  必须包含的头文件#include <vector>

Ø  vector支持随机存取

Ø  vector的大小(size)和容量(capacity

F  size返回实际元素个数,

F  capacity返回vector能容纳的元素最大数量。如果插入元素时,元素个数超过capacity,需要重新配置内部存储器。

构造、拷贝和析构

操作

效果

vector<T> c

产生空的vector

vector<T> c1(c2)

产生同类型的c1,并将复制c2的所有元素

vector<T> c(n)

利用类型T的默认构造函数和拷贝构造函数生成一个大小为nvector

vector<T> c(n,e)

 

产生一个大小为nvector,每个元素都是e

vector<T> c(beg,end)

产生一个vector,以区间[beg,end]为元素初值

 

非变动操作

操作

效果

c.size()

返回元素个数

c.empty()

判断容器是否为空

c.max_size()

返回元素最大可能数量(固定值)

c.capacity()

返回重新分配空间前可容纳的最大元素数量

c.reserve(n)

扩大容量为n

c1==c2

判断c1是否等于c2

c1!=c2

判断c1是否不等于c2

c1<c2

判断c1是否小于c2

c1>c2

判断c1是否大于c2

c1<=c2

判断c1是否大于等于c2

c1>=c2

判断c1是否小于等于c2

 

赋值操作

操作

效果

c1 = c2

c2的全部元素赋值给c1

c.assign(n,e)

将元素en个拷贝赋值给c

c.assign(beg,end)

将区间[beg,end]的元素赋值给c

c1.swap(c2)

c1c2元素互换

swap(c1,c2)

同上,全局函数

 

元素存取

操作

效果

at(idx)

返回索引idx所标识的元素的引用,进行越界检查

operator [](idx)

 

返回索引idx所标识的元素的引用,不进行越界检查

front()

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

back()

 

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

 

迭代器相关函数

操作

效果

begin()

返回一个迭代器,指向第一个元素

end()

返回一个迭代器,指向最后一个元素之后

rbegin()

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

rend()

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

 

安插元素

操作

效果

c.insert(pos,e)

pos位置插入元素e的副本,并返回新元素位置

c.insert(pos,n,e)

pos位置插入n个元素e的副本

c.insert(pos,beg,end)

pos位置插入区间[beg,end]内所有元素的副本

c.push_back(e)

在尾部添加一个元素e的副本

 

移除元素

操作

效果

c.pop_back()

移除最后一个元素但不返回最后一个元素

c.erase(pos)

删除pos位置的元素,返回下一个元素的位置

c.erase(beg,end)

删除区间[beg,end]内所有元素,返回下一个元素的位置

c.clear()

移除所有元素,清空容器

c.resize(num)

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

c.resize(num,e)

 

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

 

 

 

vector应用实例:

#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;
}


5.map/multimap

Ø  使用平衡二叉树管理元素

Ø  元素包含两部分(key,value)keyvalue可以是任意类型

Ø  必须包含的头文件#include <map>

Ø  根据元素的key自动对元素排序,因此根据元素的key进行定位很快,但根据元素的value定位很慢

Ø  不能直接改变元素的key,可以通过operator []直接存取元素值

Ø  map中不允许key相同的元素,multimap允许key相同的元素

构造、拷贝和析构

操作

效果

map c

产生空的map

map c1(c2)

产生同类型的c1,并复制c2的所有元素

map c(op)

op为排序准则产生一个空的map

map c(beg,end)

以区间[beg,end]内的元素产生一个map

map c(beg,end,op)

op为排序准则,以区间[beg,end]内的元素产生一个map

~ map() 

销毁所有元素并释放内存。

 

非变动性操作

操作

效果

c.size()

返回元素个数

c.empty() 

判断容器是否为空

c.max_size() 

返回元素最大可能数量

c1==c2

判断c1是否等于c2

c1!=c2

判断c1是否不等于c2

c1<c2

判断c1是否小于c2

c1>c2

判断c1是否大于c2

c1<=c2

判断c1是否大于等于c2

c1>=c2

判断c1是否小于等于c2

 

赋值

操作

效果

c1 = c2

c2的全部元素赋值给c1

c1.swap(c2) 

c1c2的元素互换

swap(c1,c2) 

同上,全局函数

 

特殊搜寻操作

操作

效果

count(key) 

返回键值等于key”的元素个数

find(key) 

返回键值等于key”的第一个元素,找不到返回end

lower_bound(key)

返回键值大于等于key”的第一个元素

upper_bound(key)

返回键值大于key”的第一个元素

equal_range(key)

返回键值等于key”的元素区间

 

迭代器相关函数

操作

效果

begin()

返回一个双向迭代器,指向第一个元素

end()

 

返回一个双向迭代器,指向最后一个元素之后

rbegin() 

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

rend()

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

 

安插元素

操作

效果

c.insert(e) 

c.insert(beg,end) 

 

插入e的副本,并返回新元素位置

将区间[beg,end]内所有元素的副本插入到c

 

 

移除元素

操作

效果

c.erase(pos) 

删除迭代器pos所指位置的元素,无返回值

c.erase(val)

 

移除所有值为val的元素,返回移除元素个数

c.erase(beg,end) 

 

删除区间[beg,end]内所有元素,无返回值

c.clear() 

移除所有元素,清空容器

 

map应用实例:

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

struct T1{
    int v;
    bool operator<(const T1 &a)const{
        return (v < a.v);
    }
};

struct T2{
    int v;
};
struct cmp{
    const bool operator()(const T2 &a, const T2 &b){
        return (a.v < b.v);
    }
};

int main(){
    map<T1, int>mt1; //example for user-defined class
    map<T2, int, cmp>mt2; //example for user-defined class(functor)

    map<string, int> m2;
    map<string, int>::iterator m2i, p1, p2;
    //map<string, int, greater<string> >m2;
    //map<string, int, greater<string> >::iterator m2i, p1, p2;
    m2["abd"] = 2;
    m2["abc"] = 1;
    m2["cba"] = 2;
    m2.insert(make_pair("aaa", 9));
    m2["abf"] = 4;
    m2["abe"] = 2;
    cout << m2["abc"] << endl;

    m2i = m2.find("cba");
    if(m2i != m2.end()){
        cout << m2i->first << ": " << m2i->second << endl;
    }else{
        cout << "find nothing" << endl;
    }

    cout << "Iterate" << endl;
    for(m2i = m2.begin(); m2i != m2.end(); m2i++){
        cout << m2i->first << ": " << m2i->second << endl;
    }

    return 0;
}


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));
    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;
}


6.算法

1count:

template<class InIt, class T>

size_t count(InIt first, InIt last,const T& val);

计算[first,last) 中等于val的元素个数

2count_if

template<class InIt, class Pred,class Dist>

size_t count_if(InIt first, InIt last,Pred pr);

计算[first,last) 中符合pr(e) == true 的元素e的个数

3for_each

template<class InIt, class Fun>

Fun for_each(InIt first, InIt last,Fun f);

[first,last)中的每个元素 e ,执行 f(e) , 要求 f(e)不能改变e

4find

template<class InIt, class T>

InIt find(InIt first, InIt last, constT& val);

返回区间[first,last) 中的迭代器 i ,使得 * i == val

5find_if

template<class InIt, class Pred>

InIt find_if(InIt first, InIt last, Predpr);

返回区间[first,last) 中的迭代器 i, 使得 pr(*i) == true

6binary_search 折半查找,要求容器已经有序且支持随机访问迭代器,返回是否找到

template<class FwdIt, class T>

 bool binary_search(FwdIt first, FwdIt last,const T& val);

上面这个版本,比较两个元素x,y 大小时, x < y

template<class FwdIt, class T,class Pred>

bool binary_search(FwdIt first, FwdItlast, const T& val, Pred pr);

上面这个版本,比较两个元素x,y 大小时, pr(x,y)

7sort快速排序

template<class RanIt>

void sort(RanIt first, RanIt last);

按升序排序。判断x是否应比y靠前,就看x < y 是否为true

template<class RanIt, class Pred>

void sort(RanIt first, RanIt last, Predpr);

按升序排序。判断x是否应比y靠前,就看pr(x,y) 是否为true

template<class FwdIt>

FwdIt unique(FwdIt first, FwdIt last);

== 比较是否相等

template<class FwdIt, class Pred>

FwdIt unique(FwdIt first, FwdIt last, Pred pr);

pr 比较是否等

去除[first,last) 这个升序序列中的重复元素

返回值是迭代器,指向元素删除后的区间的最后一个元素的后面

8reverse

template<class BidIt>

void reverse(BidIt first, BidIt last);

颠倒区间[first,last)顺序

 

 

【心得体会】

运算符重载给我们提供了一种更简便、更行之有效的途径去实现各种功能,但是琐碎的知识点往往给我们在实践时带来困难。所以我们首先要尽可能地去记忆一些比较重要的知识点,然后逐渐在实践中加深对知识点的理解,做到熟练运用的目的。

c++标准模板库STLc++标准程序库的核心,为我们写代码提供了一套非常好使的工具。就拿给元素排序来说,在学STL之前我们大多使用冒泡排序法,但是冗长的代码和实现功能的低效率给我们实现功能带来了不便,而在STL中有一种快速排序法叫做sort排序,一条语句就可以高效率实现我们想要实现的功能。所以,我们在以后写代码的过程中,要有意识地运用STL中的功能函数,提高代码实现的速率。就拿我们最近一直在写的模拟ATM系统来说,记录类中的记录数组可以用动态数组vector来代替普通数组r,按存钱方式、存钱时间来查找交易记录可以通过map/multimap来实现。当然,在实现的过程中会有种种困难,这需要我们在不断修改、不断完善的基础上去得到更好的代码。

 

   

 

 

 

 

  

 

   

 

 

    

   

 

   

 

   

 

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告