在编程过程中,有时候一些运算符的功能已不能满足我们的需要,这个时候,我们就可以根据自己的需要重载运算符,添加或改变该运算符的功能。在C++中大部分运算符都可以重载,但仍有几个桀骜不驯的家伙。
例如:. .* :: ?: sizeof
当然,运算符的重载也要有一定的“潜规则“,不可能让你乱来。以下便是运算符重载的限制条件:
(1)不改变运算符的优先级;
(2)不改变运算符的结合性;
(3)不改变运算符的操作数;
(4)不能创建新的运算符;
运算符的重载可以用成员函数或友元函数来完成。
成员函数格式:
//类内定义:
class L
{
返回类型 operstor X(形参表)
};
//类外定义:
返回类型 L::operator X(形参表) //X在此处为需要被重载的运算符;
{
//相对于该类定义的操作
}
例:
#include <iostream.h>
class Complex
{
double real;
double imag;
public:
Complex( ) {real=0,imag=0;}
Complex(double r,double i) {real=r; imag=i;}
Complex operator + (Complex &c2); //重载+用于复数运算
void display( );
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;
}
友元函数格式:
//在类内定义
friend 类名 operatorX(形参表)
//类外定义
类名 operatorX(形参表)
{
//相对于该类定义的操作;
}
例:
class Time
{
int month,day,hour,minute;
public:
Time(){};
Time(int,int,int,int);
Time(int,int);
void SetTime(int,int,int,int);
void display();
int getmonth(){return month;};
int getday(){return day;};
int gethour(){return hour;};
int getminute(){return minute;};
friend ostream & operator<<(ostream &out,const Time &); //重载输出流输出时间;
};
ostream & operator<<(ostream &out,const Time &date)
{
out<<date.month<<" "<<date.day<<" "<<date.hour<<" "<<date.minute<<endl;
return out;
}
class Record
{
int no;
Time date;
string type;
int jine;
double yue;
public:
Record(){};
Record(int,Time,string,int,double);
Record(Time,string,int,double);
void SetRecord(int,Time,string,int,double);
void display();
string gettype(){return type;};
Time getdate(){return date;}
friend ostream & operator<<(ostream &out,Record &r); //重载输出流由于输出记录;
};
ostream & operator<<(ostream &out,Record &r)
{
out<<r.no<<" "<<r.date.getmonth()<<" "<<r.date.getday()<<" "<<r.date.gethour()<<" "<<r.date.getminute()<<" "<<r.type<<" "<<r.jine<<" "<<r.yue;
return out;
}
class User
{
int no; //账号
string name; //姓名
string mima; //密码
double yue; //余额
Record r[200]; //交易记录
int num; //交易记录数
public:
User(){};
User(int,string,string,double,int); //账号,姓名,密码,余额,交易记录数
User(int,string,string,double); //账号,姓名,密码,余额
void SetUser(int,string,string,double);
void setno(int a){no=a;};
void setyue(double a){yue=a;};
void SetUser(double a){yue=a;};
int getno(){return no;};
double getyue(){return yue;};
string getmima(){return mima;};
string getname(){return name;};
friend bool operator<(Time,Time); //重载<用于比较时间;
friend bool operator==(Time,Time);
void display(); //交易记录数为0时不显示
void add(Record); //增加一条记录
void disRecord(int); //显示一条记录
void disAllRecord(); //显示所有记录;
void queryByTime(Time,Time); //通过时间查找记录
void queryByType(string); //通过交易类型查找记录
};
bool operator<(Time t1,Time t2)
{
bool t=true;
if(t1.getmonth()<t2.getmonth())
return t;
else
{
if(t1.getmonth()>t2.getmonth()) {return false;}
else
{
if(t1.getday()<t2.getday()||t1.getday()==t2.getday()) return t;
else {return false;}
}
}
}
注意:= () [] -> 不能被友元函数重载;
关于STL
概述:
容器(Container) - 管理某类对象的集合;
迭代器(Iterator) - 在对象集合上进行遍历;
算法(Algorithm) - 处理集合内的元素;
容器适配器(containeradaptor);
函数对象(functor);
容器类别:
序列式容器-排列次序取决于插入时机和位置;
关联式容器-排列顺序取决于特定准则;
此处主要介绍vector(向量),map
vector
初始化:vector<数据类型(可以是用户自定义的类)> 向量的名称
生成迭代器(类似指针,有书籍形象的将其比作标签,用于历遍元素)
迭代器初始化:vector<数据类型(可以是用户自定义的类)> const_iterator 迭代器名称 (只读)
vector<数据类型(可以是用户自定义的类)> iterator 迭代器名称 (读、写)
历遍元素:
设迭代器的名称为 iter
for (iter = 向量名.begin();iter !=向量名.end();++iter)
vector部分自带函数:
begin() 返回一个迭代器,指向第一个元素
end() 返回一个迭代器,指向最后一个元素之后
insert(pos(迭代器),e) 在pos位置插入e的副本
push_back(e) 在向量末尾插入e的副本
pop_back() 移除最后一个元素
clear() 移除所有元素,清空容器
map/multimap<key,value>(multimap允许key相同的元素)
格式 map/multimap<类型,类型> 名称
大概是将两个类型绑定到一起
迭代器与vector相似
map部分自带函数(大部分与vector的类似)
make_pair(type1,type2) 向map的末尾插入元素
心得:如果说重载运算符是一种可以改变运算符功能,实现需求功能的手段。那么STL应该就算是一个标配的工具箱。在写程序时可以将里面的东西直接拿出来使用,使我们的代码变得更为简洁。当然,现在对于向量等运用还不算熟练,就像写ATM之前对类与对象似懂非懂,写完之后感觉很简单一样,需要更多的练习才能让自己对STL了解得更透彻。