c++ primer(第五版)筆記 第十二章 動態內存(2)

// 動態數組
#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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章