您的位置:首页 > 编程语言 > C语言/C++

c++ primer(第五版)笔记 第十二章 动态内存(2)

2014-11-11 18:21 148 查看
// 动态数组
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: