// 动态数组
#inlcude <memory>
#inlcude <string>
int main(){
// 分配要求数量的对象,返回第一个对象的指针
// []内必须是整型,不要求常量
// ()内为初始化值
int *p = new int[ 99]( 0);
// 可以分配大小为0 的动态数组,但不能解引用
int *p1 = new int[0];
// 动态数组的释放
// 释放动态数组时忘记[],或释放单一对象时使用[],行为未定义
delete [] p;
delete [] p1;
// 智能指针 unique_ptr 和动态数组
unique_ptr< int[]> upi ( new int[99]);
upi.release(); //自动释放
// 因为指向数组,所以不支持成员访问运算,可以使用下标
for( size_t i = 0; i != 99; ++i){
upi[i] = i;
}
// 如果使用 shared_ptr ,必须提供删除器
shared_ptr< int[]> spi ( new int[99], []( int *p){ delete [] p})
spi.reset();
// shared_ptr 不提供下标运算
for( size_t i = 0; i != 99; ++i){
*(spi.get() + i) = i;
}
// allocator 类定义于 memory 头文件中
// allocator 类及其算法
// allocator< T> a 定义一个 allocator 对象,可以为 T 类型的对象分配内存
// a.allocate( n) 分配一段未构造的内存,保存 n 个 T 类型的对象
// a.deallocate( p, n) 释放从 p 中地址开始的内存,p 是 allocate 返回的指针,n 为 p 创建时要求的大小,调用 deallocate 前必须对每个在此内存中的创建的对象调用 destroy
// a.construct( p, args) p 是一个指向原始地址的指针, args 被传递给 T 类型的构造函数,用来在 p 指向的内存中构造一个对象
// a.destroy( p) p 为 T* 类型的指针,此算法对 p 指向的对象执行析构函数
// 拷贝和填充未初始化内存的算法,定义于 memory 头文件中
// uninitialized_copy( b, e, b2) 从迭代器 b e 指定的范围内拷贝元素到迭代器 b2 制定的未初始化的原始内存中,b2 指向内存必须足够大,容纳所有拷贝
// uninitialized_copy_n( b, n, b2) 从迭代器 b 指向的元素开始,拷贝 n 个元素到 b2 开始的内存中
// uninitialized_fill( b, e, t) 在迭代器 b e 指定的原始范围中创建对象,对象的值均为 t 的拷贝
// uninitialized_fill_n( b, n, t) 在迭代器 b 指向的内存地址开始创建 n 个对象,b 必须足够大
return 1;
}
查找单词练习
//query_result.h
#ifndef QUERYR_ESULT_H_
#define QUERY_RESULT_H_
#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <memory>
class QueryResult{
using line_no = std::vector< std::string>::size_type;
friend std::ostream& print( std::ostream&, const QueryResult&);
public:
QueryResult( std::string s,
std::shared_ptr< std::set< line_no>> p,
std::shared_ptr< std::vector< std::string>> f):
word( s), lines( p), file( f) {}
private:
std::string word;
std::shared_ptr< std::set< line_no>> lines;
std::shared_ptr< std::vector< std::string>> file;
};
#endif //QUERYRESULT_H_
// query_result.cc
#include "query_result.h"
std::ostream& print( std::ostream& os, const QueryResult& qr){
os << qr.word << " " << qr.lines->size() << " "
<< "times" << std::endl;
for(auto num : *qr.lines){
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << std::endl;
}
return os;
}
// text_query.cc
#ifndef TEXTQUERY_H_
#define TEXTQUERY_H_
#include <fstream>
#include <sstream>
#include <memory>
#include <vector>
#include <string>
#include <map>
#include <set>
class QueryResult;
class TextQuery{
public:
using line_no = std::vector< std::string>::size_type;
TextQuery( std::ifstream &);
QueryResult query( const std::string &) const;
private:
std::shared_ptr< std::vector< std::string>> line_array; //input file
std::map< std::string, std::shared_ptr< std::set< line_no>>> word_map; //a map :word line_no
};
#endif //TEXTQUERY_H_
// text_query.cc
#include "text_query.h"
#include "query_result.h"
TextQuery::TextQuery(std::ifstream &ifs){
std::string line;
while( getline( ifs, line)){ //从文件流中读取每一行
line_array->push_back( line); //压入数据成员中
int n = line_array->size(); //行号
std::istringstream iss( line); //字符串流
std::string word;
while(iss >> word){ //读取没个字符
auto &lines = word_map[ word]; //检索 map
if( !lines)
lines.reset( new std::set< line_no>); //如果不存在,创建新动态内存
lines->insert( n); //添加行号
}
}
}
QueryResult TextQuery::query( const std::string &word) const{
static std::shared_ptr< std::set< line_no>> nodata( new std::set< line_no>);
auto res = word_map.find( word);
if( res == word_map.end())
return QueryResult( word, nodata, line_array);
else
return QueryResult( word, res->second, line_array);
}
// search word in file
#include "text_query.h"
#include "query_result.h"
#include <fstream>
int main(){
std::ifstream ifs("test.txt");
TextQuery tp(ifs);
while( true){
std::cout << "enter a word to look for, or q ro quit: ";
std::string s;
if(!(cin >> s) || s == 'q')
break;
print( std::cout, tp.query(s)) << endl;
}
return 1;
}