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