|
1.用成员函数重载运算符 |
class x{ //... 返回类型 operator 运算符(形参表); }; 返回类型 X:operator 运算符(形参表) { 函数体; }
|
例如(重载+使复数相加) |
#include
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<2.上面的operator+还可以改写的更简练一些。Complex Complex::operator+(Complex &c2) { return Complex(real+c2.real,image+c2.image);}
|
3.注意重载运算符后,不改变其原来的功能。不改变运算符的优先级别。 |
4.对运算符重载的函数有两种处理方式(1)把运算符重载的函数作为类的成员函数;(2)运算符重载的函数不是类的成员函数,在类中把它声明为友元函数。 |
#include
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<注意和不是友元函数的区别。
|
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
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<=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<
|
STL |
1.vector vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。为了可以使用vector,必须在你的头文件中包含下面的代码:#include 构造函数。
用法 vectorc 产生空的vector. vectorc1(c2) 产生同类型的才,并复制c2的所有元素。 vectorc(n)生成容器为n的vector。 vectorc(beg,end)产生一个vector以区间[beg,end]为元素初值、 ~vector()销毁所有元素,并释放内存。 |
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 #include #include using namespace std; int main(){ vector 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 #include int main(){ multimap mm1; multimap::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
#include
#include
|
最后给大家分享一下心得。 首先,运算符重载是很重要的,很有实用意义,丰富了类的功能和适用范围,重载时一般都是基于原来的功能进行延伸不能太违背原来的意思,比如
|
把加号重载成小于号用。重载一次一劳永逸,为下面节省很多,而且使程序更清晰。STL 使是以模板为基础的一个标准库,使c++的重要的一部分。 它非常有实用性,运用STL能使代码更简洁。我们要对STL各种容器及其特有的一些功能都要了解,用的时候也便于查找。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|