1、关联容器的迭代器是双向迭代器。
2、有序关联容器的关键字类型:
3、pair类型:make_pair(v1,v2),返回一个用v1和v2初始化的pair。
///程序8
pair<string,int> preocess(vector<string> &v){
if(!v.empty())
return {v.back(),v.back().size()};//列表初始化
else
return pair<string,int>();//隐式构造返回值
}
4、关联容器操作
5、添加元素。insert(emplace)方法:会返回一个pair类型,fisrt是一个迭代器,指向具体给定关键字的元素;sencod为bool类型,插入是否成功
//map的几种插入方式:
word_map.insert({word,1});
word_map.insert(make_pair(word,1));
word_map.insert(pair<string,int>(word,1));
word_map.insert(map<string,int>::value_type(word,1));
6、元素访问(find,count,lower_bound,upper_bound,equal_range)
lower_bound,upper_bound:前:返回一个迭代器,指向第一个关键字不小于k的元素;后:指向第一个关键字大于k的元素
equal_range:返回一个迭代器pair,表示关键字等于k的元素范围。若k不存在,pair的两个成员均等于end();
1、shared_ptr与unique_ptr,在头文件memory中
shared_ptr sp;
unique_ptr up;//空智能指针,指向类型为T的对象
p;//若P指向一个对象,则为true
*P;
p->mem <==> (*p).mem;
p.get();//返回p中保存的指针
make_shared(args);//使用args初始化一个指向T对象的shard_ptr
shared_ptr p(q);//p为q的拷贝,增加q中的引用计数
p = q;//在p和q都是shared_ptr的情况下,p的引用计数会减少,q的引用计数会增加
shared_ptr p(q);//q必须指向new分配的内存
shared_ptr p(u);//接管u(unique_ptr)的所有权,将u置空
shared_ptr p(q,d);//p接管q的所有权,并且可调用d来代替delete
/*
void end_connect(connection *p){disconnect(*p);}
connection c = connect(&d);
shared_ptr p(&c,end_connect);
*/
q.reset();//若q是唯一指向对象shared_ptr,释放此对象
q.reset(p);//令q指向p
q.reset(p,d);
unique_ptr u;
unique_ptr u;//指定类型为D的对象代替delete(P419有具体例子)
u = nullptr;//释放u,并置空
u.release();//释放u,并返回u所指向的指针
u.reset();
u.reset(p);//若存在p,则u指向p;否则置空
///程序1
void test_uniqueptr(){
unique_ptr<string> p1(new string("TEST"));
unique_ptr<string> p2(p1.release());//转移所有权,并置空p1;
//p2.release();//error,p2不会释放,而且丢失了指针
auto p = p1.release();//ok,记得delete(p)
}
①接受指针参数的智能指针的构造函数是explicit的,因此不能将一个内置的指针转换为智能指针,必须使用显示初始化形式
shared_ptr<int> p1 = new int(1024);//error
shared_ptr<int> p2(new int(1024));//ok
//返回
shared_ptr<int> clone(int p){
//return new int(p);//error 不能隐式转换一个普通的指针
return shared_ptr<int>(new int(p));
}
②不能混用普通指针和智能指针
//程序2
//在调用process时,ptr创建并被初始化
void process(shared_ptr<int> ptr){
//使用ptr
}//ptr离开作用域,被销毁
void test_smart_ptr(){
shared_ptr<int> p(new int(42));//引用计数为1
process(p);//拷贝,在process中引用计数为2
int i = *p;//ok,引用计数为1
}
void test_com_ptr(){
int *x(new int(42));
process(x);//不能将int *传递给shared_ptr
process(shared_ptr<int> (x));//临时的shared_ptr,参数传递完后,引用计数会减少
int i = *x;//未定义
}
unique_ptr<int> clone(int p){
return unique_ptr<int> (new int(p));//ok
}
unique_ptr<int> clone(int p){
unique_ptr<int> ret(new int(p));
return ret;//ok
}
2、动态数组
unique_ptr<int []> up(new int[10]);
up.release();//自动调用delete[]
for(size_t i = 0; i != 10; i++)
up[i] = i;//unique_ptr访问数组
//使用shared_ptr
shared_ptr<int> sp(new int[10],[](int *p){delete[] p;});
sp.reset();//使用提供的lambda释放数组
for(size_t i = 0; i != 10; i++)
*(sp.get()+i) = i;
3、使用与管理动态内存
4、文本查询程序
///程序3
//头文件TextQuery.h
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using line_no = vector<string>::size_type;
//前向声明(不完全类型),可以定义其指针、引用、或者作为函数的参数或返回值
class QueryResult;
class TextQuery
{
public:
TextQuery(ifstream &);
QueryResult query(const string &) const;
private:
shared_ptr<vector<string>> file;//输入文件
map<string,shared_ptr<set >> wm;//每个单词与对应行号的集合
};
class QueryResult
{
friend ostream & print(ostream &,const QueryResult &);
public:
QueryResult(string s,
shared_ptr<set > p,
shared_ptr<vector<string>> f):
sought(s),lines(p),file(f){}
private:
string sought;
shared_ptr<set > lines;
shared_ptr<vector<string>> file; //将与TextQuery共用一个file,智能指针引用计数机制
};
#endif // TEXTQUERY_H
//TextQuery.cpp
#include "TextQuery.h"
#include
TextQuery::TextQuery(ifstream &is):file(new vector<string>)
{
string text;
while (getline(is,text)) { //读取每行数据
file->push_back(text); //保存当前行
int num = file->size() - 1; //行号
istringstream line(text); //分割每个单词
string word;
while (line >> word) {
auto &lines = wm[word]; //lines为shared_ptr类型
if(!lines)
lines.reset(new set );
lines->insert(num);
}
}
}
QueryResult TextQuery::query(const string &sought) const
{
static shared_ptr<set > nodata(new set );
auto loc = wm.find(sought);
if(loc == wm.end())
return QueryResult(sought,nodata,file);
else
return QueryResult(sought,loc->second,file);
}
ostream &print(ostream &os, const QueryResult &qr)
{
os << qr.sought << "occurs" << qr.lines->size() << " times" << endl;
for(auto num: *qr.lines)
os << "\t(line "<< num+ 1 <<")" << *(qr.file->begin() + num) << endl;
return os;
}