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

31 篇文章 0 订阅
// 动态数组
#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值