一:运算符重载
1、基本概念:运算符重载使得用户自定义的数据以一种更简洁的方式工作。
(1)声明与定义格式
类内声明:
class X
{
返回类型 operator运算符(形参表);
}
类外定义:
返回类型X::operator运算符(形参表)
{函数体}
(2)双目运算符重载为成员函数,形参表中只有一个参数,作为运算符的右操作数,当前对象作为左操作数,通过this指针隐式传递给函数。
用重载运算符加号来实现复数的加减,重载为成员函数,只有一个参数,代表右操作数,左操作数是对象本身。
(3)单目运算符重载为成员函数,参数表中没有参数,此时当前对象作为运算符的一个操作数。
无形参时代表前自增,返回自加后对象,有形参代表后自增,返回自加之前的对象。
2、用友元函数重载
(1)常用于运算符左右操作数类型不同的情形
在第一个函数需要隐式转换的情形下,使用友元函数重载
友元函数没有this指针时,所需操作数都需在参数表显示声明。
用友元函数重载,做复数加减运算,左右操作数都需显示声明。
(2)与成员函数重载的区别
比成员函数少一个参数
操作数类型不同,必须友元重载
3、常用重载函数应用:
(1)赋值运算符重载用于对象数据的复制
opertaor=必须重载为友元函数
重载函数原型
类名&类名::operator=类名
重载=与复制构造函数类似作用,但要注意复制构造函数是构造对象时调用,重载赋值运算符是对象构造完成后调用。
(2)重载运算符[]和()
是二元运算符,只能用成员函数重载。
[]下标运算符,访问数据对象的元素
模拟动态数组,new int动态分配空间,重载下标运算符访问特定数据成员
()用于函数调用 格式:类型 类::operator()参数表
()可以看做调用函数,计算两个数的平方之和
(3)重载输入输出流(重点,常用)
重载输入输出流只能用友元
一般格式如下
重载输出流:
ostream&operator<<(ostream& out,class_name&obj)
{ out<<obj.item1;
out<<obj.item2;
out<<obj.itemn;
returnout;
}
重载输入流:
istream&operator>>(istream& in,class_name&obj)
{ in>>obj.item1;
in>>obj.item2;
in>>obj.itemn;
returnin;
}
4、重载运算符中最常见的就是输入输出及小于大于号运算符,在一些时候重载运算符很方便,以一个程序为例:
#include<bits/stdc++.h>
using namespace std;
class complexs
{
private:
int real;
int imag;
public:
complexs()
{
real=0;
imag=0;
}
complexs(int a,intb):real(a),imag(b){}
complexs operator+(complexs &c);//complexs为返回类型,重载加号运算符;
friendistream&operator>>(istream&,complexs&c);//重载输入运算符
friendostream&operator<<(ostream&,complexs&c);//重载输出运算符
friend booloperator<(complexs &c1,complexs &c2);//重载小于号运算符1
bool operator<(complex &c)//重载小于号运算符2;两种方法都行
{
return (real<c.real&&imag<c.imag);
{
voidshow(){cout<<real<<"\t"<<imag<<endl;};
};
bool operator<(complexs &c1,complexs&c2)
{
return c1.real<c1.imag;
}
istream&operator>>(istream&input,complexs&c)
{
cout<<"please inputreal and imag \t";
input>>c.real>>c.imag;
return input;
}
ostream&operator<<(ostream&output,complexs&c)
{
if(c.imag>0)output<<"("<<c.real<<"+"<<c.imag<<"i)";//而且,在重载过程中可以添加附加条件,便于程序调试;
elseoutput<<"("<<c.real<<c.imag<<"i)";
return output;
}
complexs complexs::operator+(complexs &c)
{
returncomplexs(real+c.real,imag+c.imag);
}
int main()
{
complexs c1(2,3),c2(2,3),c3;
c3=c1+c2;
c3.show();
complexs c4,c5,c6;
cin>>c4>>c5;
c6=c4+c5;
cout<<c6<<endl;
if(c4<c5)cout<<"YES";
else cout<<"NO";
return 0;
}
//不能用友元函数重载的运算符有:= () []
//重载=号和深复制复习
//不能用友元函数重载的运算符有:= () []
#include<bits/stdc++.h>
using namespace std;
class name
{
public:
name(char *p);
name(const name& );
name &operator=(name&n);
~name();
private:
char *ppp;
int size;
};
name::name(char *p)
{
cout<<"construct"<<p<<endl;
size=strlen(p);
ppp=new char[size+1];
if(ppp!=0)strcpy(ppp,p);
}
name::name(const name&ob)
{
cout<<"copying"<<ob.ppp<<"into\n";
size=ob.size;
ppp=new char[size+1];
if(ppp!=0)strcpy(ppp,ob.ppp);
}
name&name::operator=(name&n)
{
delete[]ppp;
size=n.size;
ppp=new char[size+1];
if(ppp!=0)strcpy(ppp,n.ppp);
return *this;//return 的是此对象 return*this;
}
name::~name()
{
cout<<"destruct"<<ppp<<endl;
ppp[0]='\0';
delete[]ppp;
ppp=NULL;
size=0;
}
int main()
{
name obj("lalaa");
name obj2=obj;
name obj3("hahah");
obj3=obj2=obj;
二:STL
1、STL主要包括容器,目前最常用的就是vector;还有迭代器,相当于容器的一个副本,对元素进行遍历;还有算法,也就是对元素进行各种操作,有特殊的语句来执行。
(1)容器:
管理某类对象的集合,分为关联式容器(次序取决于插入时机位置)和序列式(取决于特定准则)
共同操作:
初始化、与大小相关的操作(size max_size() empty())、比较、赋值和交换、与迭代器相关的操作:(begin()、end()、rbegin()、rend())、元素操作(insert(pos,e)、erase(beg,end)、clear())
注:begin()返回第一个元素,end()返回最后一个元素之后
(2)迭代器::iterator
遍历STL容器内全部或部分元素
指出容器内特定元素位置
迭代器分类:
双向迭代器、随机存取迭代器
2、vector(重)
(1)基本概念:
vector模拟动态元素,元素可以是任意类型
必须包含头文件#include<vector>
vector支持随机存取
vector大小size(返回实际元素个数)和容量capacity(返回元素最大数量)
(2)、赋值:
c1=c2;
c.assign(n,e);将元素e的n个赋值拷贝给c
c.swap(c1);c1,c元素互换
swap(c,c1);同上
(3)操作
vector<T>c : 产生空的vector
vector<T>c1(c2) :产生同类型的c1,并将复制c2的所有元素
vector<T>c(n) : 利用类型T的默认构造函数和拷贝构造函数生成一个大小为n的vector
vector<T>c(n,e) : 产生一个大小为n的vector,每个元素都是e
vector<T>c(beg,end) : 产生一个vector,以区间[beg,end]为元素初值
vector<T>() : 销毁所有元素并释放内存。
c.empty() 判断容器是否为空
c.capacity() 返回重新分配空间前可容纳的最大元素数量
c.reserve(n) 扩大容量为n
c1= c2 将c2的全部元素赋值给c1
c.assign(beg,e[beg,end]nd) 将区间的元素赋值给c
at(idx) 返回索引idx所标识的元素的引用,进行越界检查
operator[](idx) 返回索引idx所标识的元素的引用,不进行越界检查
front() 返回第一个元素的引用,不检查元素是否存在
back() 返回最后一个元素的引用,不检查元素是否存在
c.push_back(e) 在尾部添加一个元素e的副本
c.pop_back() 移除最后一个元素但不返回最后一个元素
vector<int> a;//定义一个元素类型为int,名称为a 的动态数组。
for (int i = 0; i < 5; ++i){
a.push_back(5 - i);//将5 4 3 2 1 依次放入a 里面
}
cout << "Size: " << a.size() << endl; //a当前的大小
a.pop_back(); //移除a 的最后一个元素
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();//清除a中所有元素
cout << "Size: " << a.size() << endl;
3、map和multimap
(1)基本概念:
使用平衡二叉树管理,元素包括两部分(key,value),key是关键字,value是值,包含头文件#include<map>,map的key不同,multimap的key可以相同。
(2):
元素包含两部分(key,value),key和value可以是任意类型
必须包含的头文件#include <map>
根据元素的key自动对元素排序,因此根据元素的key进行定位很快,但根据元素的value定位很慢
不能直接改变元素的key,可以通过operator[]直接存取元素值
map中不允许key相同的元素,multimap允许key相同的元素
(3)、multimap<string, int> mm1;//定义一个索引key是string,值valua是int的,名为mm1的
multimap<string, int>::iterator mm1i, p1, p2;//定义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;
}
4、set、multiset、pair
(1)set、multiset基本概念
使用平衡二叉树管理,包含头文件#include<set>,set是单纯的键的集合,set不允许键相同,multiset允许。
建立关键字字符串型的set,插入元素,建立迭代器,从头到尾遍历,输出元素值,再建立迭代器查找特定元素。
multiset类似,但可以有多个键相同的元素。
(3)pair生成key-value对
5、算法
count 计算一段范围内等于某个值的元素个数
count_if 计算一段范围内满足某个条件的元素个数
max_element 返回一段范围内最大元素的迭代器
for_each 遍历一段范围内的元素,调用函数
find 寻找特定元素第一次出现的位置,返回迭代器。
find_if 返回区间范围内满足制定条件的迭代器
binary_search折半查找,返回是否找到
lower_bound返回大于等于指定值的最小位置
upper_bound返回大于指定值的最小位置
sort快速排序,可以加一个条件形参,按条件排序
unique去重,返回迭代器,指向元素删除后区间最后一个元素后面
reverse 颠倒区间端点的顺序
三、心得
近期所学习的这些新知识的作用发大概就是可以简缩所写代码,把同样的功能用更精简的程序完成,明显的实现效率更高。经过这段时间的学习,不太好意思的说还是有点蒙的,并不是太清楚对新知识的使用。老师让我们为你把原来写的ATM用新学的ATL改一遍,应该就是为了锻炼我们的实用能力,就发现掌握的真的很不好。所以以后还需要努力,在多加的学习。先记住所学知识,再一步步地去运用,在不断地实践中真正地掌握它。充分利用网上的资源,弄懂自己不会的和不清楚的,顺便扩大自己的知识面。