C++ラーニングアレンジ(コンテナとダイナミックメモリを関連付ける)


関連コンテナ
1、関連容器の反復器は双方向反復器である.2、順序付け関連コンテナのキーワードタイプ:
  • キーワードタイプは、厳密な弱いシーケンス
  • を定義する必要があります.
  • multisetは、キーワードタイプと比較オペレータ
  • の2つのタイプを提供する必要があります.
    3、pairタイプ:make_pair(v 1,v 2)は、v 1とv 2で初期化されたpairを返します.
    ///  8
      pair<string,int> preocess(vector<string> &v){
        if(!v.empty())
          return {v.back(),v.back().size()};//     
        else
          return pair<string,int>();//       
      }

    4、関連コンテナ操作
  • key_type(このようなコンテナタイプのキーワードタイプ)、mapped_type(各キーワードに関連付けられたタイプ(map)、value_type(setの場合key_typeと同様、mapの場合:pair)
  • .
  • mapに対するvalue_typeタイプは、constタイプであるため、キーワードメンバーの値を変更することはできません.

  • 5、要素を追加します.Insert(emplace)メソッド:pairタイプが返されます.fisrtは反復器で、特定のキーワードの要素を指します.sencodはboolタイプで、挿入に成功したかどうか
    //map       :
    word_map.insert({word,1});
    word_map.insert(make_pair(word,1));
    word_map.insert(pair<string,int>(word,1));
    word_map.insert(map<string,int>::value_type(word,1));
    

    6、要素アクセス(find,count,lower_bound,upper_bound,equal_range)
  • lower_bound,upper_bound:前:反復器を返し、最初のキーワードがkより小さくない要素を指します.後:最初のキーワードがkより大きい要素
  • を指す.
  • equal_range:キーワードがkの要素範囲に等しいことを示す反復器pairを返します.kが存在しない場合、pairの2つのメンバーはend()に等しい.

  • ダイナミックメモリ
    1、shared_ptrとunique_ptr、ヘッダファイルmemory
  • でサポートされているいくつかの操作
  •   shared_ptr sp;
      unique_ptr up;//     ,     T   
      p;// P      ,  true
      *P;
      p->mem <==> (*p).mem;
      p.get();//  p      
  • shared_ptr独自の操作
  •   make_shared(args);//  args       T   shard_ptr
      shared_ptr p(q);//p q   ,  q      
      p = q;// p q  shared_ptr    ,p        ,q        
  • shared_の定義と変更ptrの他の方法
  •   shared_ptr p(q);//q    new     
      shared_ptr p(u);//  u(unique_ptr)    , u  
      shared_ptr p(q,d);//p  q    ,     d   delete
      /*
      void end_connect(connection *p){disconnect(*p);}
      connection c = connect(&d);
      shared_ptr p(&c,end_connect);
      */
      q.reset();// q       shared_ptr,     
      q.reset(p);// q  p
      q.reset(p,d);
  • unique_ptrの動作
  •   unique_ptr u;
      unique_ptr u;//     D     delete(P419     )
      u = nullptr;//  u,   
      u.release();//  u,   u      
      u.reset();
      u.reset(p);//   p, u  p;    
    
      ///  1
      void test_uniqueptr(){
        unique_ptr<string> p1(new string("TEST"));
        unique_ptr<string> p2(p1.release());//     ,   p1;
    
        //p2.release();//error,p2    ,       
        auto p = p1.release();//ok,  delete(p)
      }
  • shared_ptrとnewを組み合わせて
  • を使用
    explicit ,                   ,           
      shared_ptr<int> p1 = new int(1024);//error
      shared_ptr<int> p2(new int(1024));//ok
      //  
      shared_ptr<int> clone(int p){
        //return new int(p);//error              
        return shared_ptr<int>(new int(p));
      }
    ②             
      //  2
      //   process ,ptr       
      void process(shared_ptr<int> ptr){
        //  ptr
      }//ptr     ,   
    
      void test_smart_ptr(){
        shared_ptr<int> p(new int(42));//     1
        process(p);//  , process      2
        int i = *p;//ok,     1
      }
    
      void test_com_ptr(){
        int *x(new int(42));
        process(x);//   int *   shared_ptr
        process(shared_ptr<int> (x));//   shared_ptr,      ,       
        int i = *x;//   
      }
  • uniqueを渡すptrパラメータとuniqueを返すptr:uniq_ptrはオブジェクトを指すのでunique_ptrはコピーと付与操作をサポートしていない.ただし、破棄されるuniqをコピーまたは付与することができます.ptr
  • unique_ptr<int> clone(int p){
        return unique_ptr<int> (new int(p));//ok
      }
    
      unique_ptr<int> clone(int p){
        unique_ptr<int> ret(new int(p));
        return ret;//ok
      }

    2、動的配列
  • は、割り当てられたメモリが配列タイプ
  • ではないため、動的配列に対してbeginおよびendを呼び出すことができない.
  • shared_ptr、unique_ptrと動的配列(注意区別)
  •   unique_ptr<int []> up(new int[10]);
      up.release();//    delete[]
      for(size_t i = 0; i != 10; i++)
        up[i] = i;//unique_ptr    
    
      //  shared_ptr
      shared_ptr<int> sp(new int[10],[](int *p){delete[] p;});
      sp.reset();//     lambda    
      for(size_t i = 0; i != 10; i++)
        *(sp.get()+i) = i;
  • allocatorは、メモリ割り当てをオブジェクト構造から分離できる
  • .
    3、動的メモリの使用と管理
  • ダイナミックメモリを使用する必要がある:-不明使用オブジェクトの数-不明使用オブジェクトの正確なタイプ-複数のオブジェクト間でデータを共有する必要がある
  • 管理上の注意点
  • deleteメモリを忘れないでください.メモリの漏洩を招きやすい
  • メモリを解放したオブジェクトを使用しないでください.使用前にcheck
  • として使用することに注意してください.
  • 同じメモリに対して
  • を2回解放しないでください.

    4、テキスト検索プログラム
    ///  3
      //   TextQuery.h
    #ifndef TEXTQUERY_H
    #define TEXTQUERY_H
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    using line_no = vector<string>::size_type;
    //    (     ),       、  、             
    class QueryResult;
    
    class TextQuery
    {
    public:
    
        TextQuery(ifstream &);
        QueryResult query(const string &) const;
    
    private:
        shared_ptr<vector<string>> file;//    
        map<string,shared_ptr<set>> wm;//            
    };
    
    class QueryResult
    {
    friend ostream & print(ostream &,const QueryResult &);
    public:
        QueryResult(string s,
                    shared_ptr<set> p,
                    shared_ptr<vector<string>> f):
            sought(s),lines(p),file(f){}
    private:
        string sought;
        shared_ptr<set> lines;
        shared_ptr<vector<string>> file;    //  TextQuery    file,          
    };
    
    #endif // TEXTQUERY_H
    
    //TextQuery.cpp
    #include "TextQuery.h"
    #include 
    
    TextQuery::TextQuery(ifstream &is):file(new vector<string>)
    {
        string text;
        while (getline(is,text)) {          //      
            file->push_back(text);          //     
            int num = file->size() - 1;     //  
            istringstream line(text);       //      
            string word;
            while (line >> word) {
                auto &lines = wm[word];     //lines shared_ptr  
                if(!lines)
                    lines.reset(new set);
                lines->insert(num);
            }
        }
    }
    
    QueryResult TextQuery::query(const string &sought) const
    {
        static shared_ptr<set> nodata(new set);
        auto loc = wm.find(sought);
        if(loc == wm.end())
            return QueryResult(sought,nodata,file);
        else
            return QueryResult(sought,loc->second,file);
    }
    
    ostream &print(ostream &os, const QueryResult &qr)
    {
        os << qr.sought << "occurs" << qr.lines->size() << " times" << endl;
        for(auto num: *qr.lines)
            os << "\t(line "<< num+ 1 <<")" << *(qr.file->begin() + num) << endl;
        return os;
    }