SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
C++勉強会




          C++勉強会

         Mitsutaka Takeda

              Company



         07 March 2012




                            .   .   .   .   .   .
C++勉強会




Outline



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




Topic



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




リソースとは?




    Bjarne Stroustrup (Software Development for Infrastructure)
    `A resource is anything that has to be acquired and released after use.'




                                                            .     .     .      .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




リソースの例




         メモリ
         ファイル
         Mutex
         フォント
         ブラシ
         etc




                      .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




リソース管理の問題点



    使用後に解放しなければいけない。
    解放しない(リークする)とリソースが不足する。例えばメモリ。
    void f ( ) {
      MyClass * obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。
      obj−>doSomething ( ) ; // リ ソ ー ス の 使 用 。
      ...
      delete obj ; // リ ソ ー ス の 解 放 。
    }


         潜在不具合
         リソースの使用中に例外を投げると、リソースが開放されない。




                                                         .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




リソースを確実に解放するため(その1)


    void f ( ) {
      MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。
      try{
        obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。
        obj−   >doSomething ( ) ; // リ ソ ー ス の 使 用 。
        ...
      } catch ( std : : ba d al l o c& e ){
        i f ( obj != NULL ) // リ ソ ー ス の 使 用 中 に 例 外 を 投 げ る か も 。
            delete obj ; // d e l e t e を 省 略 で き な い こ と に 注 意 。
      } catch ( . . . ) {
        delete obj ; // そ の 他 の 例 外 。
      }
        delete obj ;
    }

    保守性に問題。(バグを混入しやすい)
         処理が複雑。例外の種類により処理の切り替えが必要。
         ソースコードの変更に対して脆い。
         コードが冗長(delete文が沢山ある)。


                                                         .    .      .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




ソースコードの変更に対する脆弱性


    例えば、保守担当者が不具合対策として以下のような変更を加えた場合。
    void f ( ) {
      MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。
      try{
        obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。
        obj−   >doSomething ( ) ; // リ ソ ー ス の 使 用 。
        i f ( obj−    >isSucceed ( ) )
            r e t u r n ; // リ ソ ー ス ・ リ ー ク ! !
      } catch ( std : : ba d al l o c& e ){
        i f ( obj != NULL )
            delete obj ;
      } catch ( . . . ) {
        delete obj ;
      }
      delete obj ;
    }




                                                        .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




脆弱性に対する対策案(人に依存)



    コーディング規約(関数からのreturnは1箇所のみ等)による対策。
         見逃したら?
         ソースコード・レビューで見逃さないようにする。
         見逃したら?
         チェック・リストを作成して、レビュー時にチェックする。
         見逃したら?
         ...
    人はミスをするので、できるかぎりコンピュータに仕事をさせる。
         マーフィーの法則
         ``Anything that can go wrong will go wrong.''




                                                         .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




解決策(コンピュータに任せる)




    C++でのメモリ管理はオブジェクトに任せる。
         RAII(Resource Acquisition Is Initialization)イディオム。
    Javaやらガベージ・コレクション系の言語では無理!!




                                                          .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIの基本的な考え方


     ... 1   リソースの取得をオブジェクトの初期化(コンストラクタ)で行う。
     ... 2   リソースの解放をオブジェクトの終了処理(デストラクタ)で行う。
    C++の言語仕様で、コンストラクタが完了したオブジェクトの デストラクタの呼び出しが保証
    されている。
    MyClassのメモリ管理を行うクラス(スマート・ポインタの特殊ケース)。
    c l a s s MyClassHandle{
    public :
        MyClass * obj ;

         MyClassHandle ( ) {
           obj = new MyClass ( ) ; // コ ン ス ト ラ ク タ で リ ソ ー ス の 取 得 。
         }
         ˜MyClassHandle ( ) {
           delete obj ; // デ ス ト ラ ク タ で リ ソ ー ス の 解 放 。
         }
    };




                                                          .    .        .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIの適用(前)



    void f ( ) {
      MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。
      try{
        obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。
        obj−   >doSomething ( ) ; // リ ソ ー ス の 使 用 。
        ...
      } catch ( std : : ba d al l o c& e ){
        i f ( obj != NULL )
            delete obj ;
      } catch ( . . . ) {
        d e l t e obj ;
      }
      delete obj ;
    }

    先程のコードにRAIIを適用すると。




                                                        .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIの適用(後)


    void f ( ) {
     // リ ソ ー ス 管 理 オ ブ ジ ェ ク ト を 生 成 ・ 初 期 化 ( = リ ソ ー ス の 取 得 )
      MyClassHandle handle ;
     // リ ソ ー ス の 使 用 。
      handle . obj−>doSomething ( ) ;
      ...
    }// f の 終 了 時 に デ ス ト ラ ク タ の 呼 び 出 し 。


         注目点
         適用後のコードではプログラマが自分でリソースの解放をしなくてもよいことに注目。 ハ
         ンドルがスコープをはずれると自動的にデストラクタが呼ばれてリソースが解放される。
         たとえ例外が投げられても!!
         適用前後のコード比較
            コード量の減少
            リソース・リークの防止
            保守性の向上。コード変更後に処理の途中でreturnしてもリソース・リーク にならない。




                                                       .    .       .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIの応用


    c l a s s Pen {
    public :
       HDC hdc ;
        HPEN new pen ;
        HGDIOBJ old pen ;
        Pen (HDC hdc , Color pen color )
          : hdc ( hdc ) , old pen ( NULL){
            new pen = CreatePen ( . . . ) ; // リ ソ ー ス の 取 得 。
            i f ( new pen )
                old pen = SelectObject ( hdc , new pen ) ;
        }
        ˜Pen ( ) {
            i f ( old pen ){
                SelectObject ( hdc , old pen ) ; // 元 の ブ ラ シ に 戻 す 。
                DeleteObject ( new pen ) ; // リ ソ ー ス の 解 放 。
            }
        }
    };




                                                                 .      .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIの応用




    void draw ( ) {
      // 赤 色 の ペ ン を 作 成 。 r e d p e n オ ブ ジ ェ ク ト が 生 き て い る
      // ス コ ー プ で は 、 線 が 赤 色 に な る 。 r e d p e n オ ブ ジ ェ ク ト
      // が 破 壊 さ れ る と ペ ン の 色 は 、 元 の 色 に 戻 る 。
      Pen red pen ( hdc , RED ) ;
      . . . // 描 画 。
    }




                                                         .       .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIを利用する際の注意点



    ハンドル・クラスのコピー動作(コピー・コンスラクタと代入演算子)に注意!!
    MyClassHandle my obj1 ;
    MyClassHandle my obj2 ( my obj1 ) ; // コ ピ ー ・ コ ン ス ラ ク タ
    // リ ソ ー ス の 使 用 。 m y o b j 1 の o b j は ど う な る ?
    my obj2 . obj−>doSomething ( ) ;

    // void f ( i n t x ) ; 値 渡 し 。
    i n t x = 3;
    f (x );
    std : : cout < x < std : : endl ; // 3 と 表 示 。
                  <      <

    // void g ( MyClassHandle obj ) 値 渡 し 。
    MyClassHandle my obj3 ;
    g ( my obj3 ) ; // g の 呼 び 出 し 後 に m y o b j 3 の 状 態 は ?




                                                               .   .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIのコピー動作




         コピーを禁止

    c l a s s MyClassHandle {
    private :
        // コ ピ ー ・ コ ン ス ラ ク タ と 代 入 演 算 子 を p r i v a t e 宣 言 。
        // 実 装 は 必 要 な し 。
        MyClassHandle ( const MyClassHandle & ) ;
        const MyClassHandle& operator =( const MyClassHandle & ) ;
    };


         参照カウントを利用してリソースを共有。(shared ptrの実装)




                                                           .     .   .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIに関連してちょこっと脱線

    リソースの取得はオブジェクトの初期化で行う。 オブジェクト初期化(生成)する時点で必要な
    情報が全て揃っているのが理想。 できる限り初期化関数は避けましょう。
    c l a s s BadClass{
    public :
        void i n i t i a l i z e ( i n t x ) ; // 初 期 化 関 数 。
        void doSomething ;
    };

    BadClass obj ; // オ ブ ジ ェ ク ト の 生 成 ( 初 期 化 )
    obj . i n i t i a l i z e ( 1 ) ; // 初 期 化 関 数 に よ る オ ブ ジ ェ ク ト の " 初 期 化 "
    obj . doSomething ( ) ;

    BadClass obj2 ;
    obj2 . doSoemthing ( ) ; // バ グ ! !       initializeの呼び出し前に他の関数

    BadClass obj3 ;
    obj3 . i n i t i a l i z e ( 1 ) ;
    obj3 . i n i t i a l i z e ( 2 ) ; // 2回 初 期 化 関 数 を 呼 び 出 し て も 良 い ?




                                                                    .        .     .   .   .   .
C++勉強会
  オブジェクトによるリソースの管理。




RAIIに関連してちょこっと脱線




    初期化はコンストラクタで行う。
    c l a s s BadClass{
    public :
        BadClass ( i n t x ) ;
        void doSomething ( ) ;
    };

    BadClass obj ( 1 ) ;
    obj . doSomething ( ) ; // 初 期 化 前 に 他 の 関 数 を 呼 び 出 せ な い 。




                                                          .        .   .   .   .   .
C++勉強会
  Interfaceの設計方法




Topic



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  Interfaceの設計方法




設計指針




          Make interfaces easy to use correctly and hard to use incorrectly
          Effective C++
          できるかぎり、コンパイラにエラーをチェックさせる。(マーフィーの法則)
          C++の型システムを利用する。




                                                             .     .    .     .   .   .
C++勉強会
  Interfaceの設計方法




悪い例 その1




     悪いインターフェイスの例。
     パラメータの名前のみで、意味を区別しようとしている。

     // 2点 間 の 距 離 を 計 算 。
     i n t c a l c u l a t e D i s t a n c e ( i n t x0 , i n t y0 , i n t x1 , i n t y1 ) ;
     // ユ ー ザ 認 証 。
     bool aut he n tic ate ( std : : s t r i n g password , std : : s t r i n g user name ) ;




                                                                          .      .      .       .   .   .
C++勉強会
  Interfaceの設計方法




悪い例 その1




     // 点 ( 1 , 3 ) と 点 ( 2 , 4 ) の 距 離 を 計 算 。
     i n t distance = c a l c u l a t e D i s t a n c e ( 1 , 2 , 3 , 4 ) ; // バ グ ! !
     i n t distance = c a l c u l a t e D i s t a n c e ( 1 , 3 , 2 , 4 ) ; // 正 し い 。
     // ユ ー ザ を 認 証 。
     std : : s t r i n g user name ( " user " ) ;
     std : : s t r i n g password ( " s e c r e t password " ) ;
     // バ グ ! ! ユ ー ザ 名 と パ ス ワ ー ド が 逆 。
     bool i s a u t h e n t i c a t e d = auth ent icate ( user name , password ) ;
     // 正 し い 。
     bool i s a u t h e n t i c a t e d = auth ent icate ( password , user name ) ;

     使用方法を間違えても、誰も教えてくれない…




                                                                           .      .      .   .   .   .
C++勉強会
  Interfaceの設計方法




改善 その1



     小さなクラスを定義して利用する。

     s t r u c t Point {
     Point ( i n t x , i n t y )
       x (x) , y (y) {
     }
     int x ;
     int y ;
     }
     typedef unsinged i n t Distance ;
     // イ ン タ ー フ ェ イ ス ( 引 数 の 型 や 戻 り 値 の 型 ) を 見 た だ け で
     // 使 用 方 法 が 判 る 。
     Distance c a l c u l a t e D i s t a n c e ( Point p1 , Point p2 ) ;




                                                                    .       .   .   .   .   .
C++勉強会
  Interfaceの設計方法




改善 その2




     typedef std : : s t r i n g Password ;
     typedef std : : s t r i n g User ;

     bool aut he n tic ate ( Password login password , User a user ) ;

     User my user name ( " user " ) ;
     Password my pass ( " s e c r e t password " ) ;
     bool i s a u t h e n t i c a t e d = auth ent icate ( my pass , my user name ) ;




                                                                       .     .      .   .   .   .
C++勉強会
  Interfaceの設計方法




改善 その2 さらなる改善



     typedefではコンパイル・エラーにはならないので注意。
     User my user name ( " user " ) ;
     Password my pass ( " s e c r e t password " ) ;
     bool i s a u t h e n t i c a t e d = auth ent icate ( my user name , my password ) ; // バ グ ! !

     コンパイラーにコードの正しさをチェックさせたいときは、クラスを利用する。

     c l a s s User {
     ...
     };
     c l a s s Password {
     ...
     };

     上記のコードはコンパイル・エラー。




                                                                      .      .     .      .      .     .
C++勉強会
  Interfaceの設計方法




脱線 typedefの効用


          型名を短くできる。

     typedef unsinged long long long MyType ;
     MyType my obj = . . . ;


          型情報への参照を間接的にして局所化する。

     typedef unsinged i n t Distance ;

     // ソ ー ス コ ー ド 中 の 色 々 な 場 所 で 、
     Distance distance 1 = . . . ;
     ...
     Distance distance 100 = . . . ;

     Distanceに、unsinged intの最大値以上の値を保持する必要が。 typedefを使用していれ
     ば、変更箇所は1箇所ですむ。
          型名にドキュメント情報(人が読むための情報として)。



                                                .   .   .   .   .   .
C++勉強会
  Interfaceの設計方法




悪い例 その2




     リソースの取得と解放が別々の処理に分離されている。
     MyClass * create ( ) ;
     void r e l e a s e ( MyClass * obj ) ;


          問題点
                クライアントがreleaseを呼び忘れたら?
                release以外の方法で、deleteされたら?




                                              .   .   .   .   .   .
C++勉強会
  Interfaceの設計方法




改善 その3


     生のポインタではなくスマートポインタを利用する。
     boost : : shared ptr<MyClass> create ( ) ;

     もし、3rdパーティのライブラリで生のポインタを返すようにしている場合。
     SomeonesClass * create ( ) ;
     void r e l e a s e ( SomeonesClass * obj ) ;

     shared ptrでは、解放の処理をカスタマイズできる。

     // 第2 引 数 で 、 解 放 に 使 用 し た い 関 数 を 指 定 。
     void f ( ) {
       boost : : shared ptr<SomeoneClass> p t r ( create ( ) ,
                                                  std : : p t r f u n ( r e l e a s e ) ) ;
       ptr−>doSomething ( ) ;
     }// 自 動 的 に 解 放 。




                                                                           .      .      .    .   .   .
C++勉強会
  標準ライブラリ STLの活用




Topic



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




標準ライブラリを使用する利点




      ...1   デバッグ済み(高い信頼性)
      ...2   他のプログラマに伝わりやすい(保守性)
      ...3   自動的に性能改善される可能性あり
      ...4   コードの記述量を減らすことができる
             バグの件数はソースコードのステップ数と相関




                                     .   .   .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




STLの構造




         container(データ構造)
         iterator
         algorithm
         IO
         数値計算
         internationalization
         例外処理




                                .   .   .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




Container/Iterator/Algorithm




    Containerとは、複数のオブジェクトの集合を管理するためのコンポーネント。
    Iteratorとは、Container中の要素にアクセスするためのコンポーネント。
    Algorithmとは、Container中の要素を処理(検索、並びかえ)するためのコンポーネント。




                                       .   .   .   .     .   .
C++勉強会
  標準ライブラリ STLの活用




Container



         Sequence containers
         順序付けられたcontainer。要素の順番はcontainerに追加した順番に依存。
             vector
             deque
             list

         Associative containers
         並びかえ済みcontainer。要素の追加時に指定した基準で要素を並びかえ。
             set
             mutiset
             map
             multimap

         その他
         Container Adapters(stack、queue、priority queue)、Cの配列。




                                                      .    .    .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




Iterator




    反復子とよばれているContainer中の要素を指すオブジェクト。(Containerと Iteratorの関
    係は、配列とポインタみたいなもの)
         Random access iterator
         Bidirectional iterator
         Forward iterator




                                          .   .   .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




Algorithm




    Container中の要素の範囲に特定の処理を行うためのライブラリ。
    例:
         for each : Container中の全要素に対して処理を行う。
         find : Container中から特定の要素を探す。
         sort : Container中の要素を並びかえる。




                                               .   .   .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




使用例




     typedef std : : vector<i n t> numbers ;
     std : : vector<i n t> createNumbers ( ) {
       std : : vector<i n t> numbers ;
       f o r ( i n t i = 0; i < 10; ++ i ){
           numbers . push back ( getRandomNumber ( ) ) ;
       }
       // 昇 順 に 並 べ 替 え 。 s o r t は デ フ ォ ル ト で (<) を 利 用 し て 並 べ 替 え る 。
       std : : s o r t ( numbers . begin ( ) , numbers . end ( ) ) ;

         // 降 順 に 並 べ 替 え 。 g r e a t e r 関 数 を 利 用 し て 並 べ 替 え 。
         std : : s o r t ( numbers . begin ( ) , numbers . end ( ) , greater<i n t > ( ) ) ;
    }




                                                                             .      .      .   .   .   .
C++勉強会
  標準ライブラリ STLの活用




関数オブジェクト




    operator()をメンバ関数を保持するオブジェクト。STLを拡張するために利用する。

     s t r u c t MyGreater{
         bool operator ( ) ( i n t x , i n t y ) {
             return x > y ;
         }
     };

     // 降 順 に 並 べ 替 え 。 M y G r e a t e r 関 数 オ ブ ジ ェ ク ト を 利 用 し て 並 べ 替 え 。
     std : : s o r t ( numbers . begin ( ) , numbers . end ( ) , MyGreater ( ) ) ;




                                                                .     .     .        .   .   .
C++勉強会
  標準ライブラリ STLの活用




コーディング without STL(電話帳 氏名と電話番号を管理するプログラム)
    const i n t MAX SIZE(1000);
    Name *names = new Name[ MAX SIZE ] ;
    PhoneNumber phone numbers = new PhoneNumber [ MAX SIZE ] ;
    unsigned i n t s i z e = 0;
    void addRecord (Name name , PhoneNumber phone number ){
      i f ( s i z e >= MAX SIZE ){
          // 最 大 長 を 越 え て い る た め メ モ リ の 確 保 と デ ー タ の コ ピ ー 。
         Name * new name data = new Name[2 * s i z e ] ;
          PhoneNumber * new phone number data = new PhoneNumber[2 * s i z e ] ;
          f o r ( i n t i = 0; i < s i z e ; ++ i ){
              new name data [ i ] = names [ i ] ;
              new phone number data [ i ] = phone numbers [ i ]
          }
         Name *tmp1 = names ;
          PhoneNumber *tmp2 = phone numbers ;
          names = new name data ;
          phone numbers = new phone number data ;
          delete [ ] tmp1 ;
          delete [ ] tmp2 ;
      }
      // レ コ ー ド を 追 加 。
      names [ s i z e ] = name ;
      phone numbers [ s i z e ] = phone number ;
      ++ s i z e ;
    }
    void sortPhoneBook (Name *names , PhoneNumber * phone numbers ){ . . . }
                                                            .    .     .     .    .   .
C++勉強会
  標準ライブラリ STLの活用




コーディング with STL




    typedef std : : pair<Name, PhoneNumber> RecordType ;
    typedef std : : vector<RecordType> PhoneBook ;
    PhoneBook my phone book ;
    void addRecord (Name name , PhoneNumber phone number ) {
      my phone book . push back ( std : : make pair ( name , phone number ) ) ;
    }

    void sortPhoneBook ( PhoneBook& phone book ){
      // M y C r i t e r i a l は 自 分 が ソ ー ト し た い 基 準 を 表 現 す る 関 数 オ ブ ジ ェ ク ト 。
      std : : s o r t ( phone book . begin ( ) , phone book . end ( ) , M y C r i t e r i a ( ) ) ;
    }




                                                                         .      .      .      .       .   .
C++勉強会
  標準ライブラリ STLの活用




STLを利用するさいにも色々な注意点が。




    それは次の機会に。




                       .   .   .   .   .   .
C++勉強会
  防衛的プログラミング




Topic



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  防衛的プログラミング




変数のスコープを最小限に
    // ル ー プ 変 数 ( i ) は 、 f o r の 初 期 化 ブ ロ ッ ク で 。
    f o r ( i n t i = 0; i < N; ++ i ) {
        ...
    }

    void bad ( ) {
      // 関 数 の 頭 で 全 変 数 を 宣 言 。
      i n t x = 0;
      std : : s t r i n g s t r ( "My name i s " ) ;
      ...
      s t r += " Takeda " ;
      ...
      ++x ;
    }
    void b e t t e r ( ) {
      ...
      std : : s t r i n g s t r ( "My name i s " ) ;
      s t r += " Takeda " ;
      ...
      i n t x = 0;
      ++x ;
    }
    void best ( ) {
      ...
      const std : : s t r i n g s t r ( "My name i s Takeda " ) ;
      ...
      i n t x = 1;                                                  .   .   .   .   .   .
C++勉強会
  防衛的プログラミング




constの活用




    できる限りconstを使用する。

    c l a s s MyClass {
    public :
        void doSomething ( ) const ; // c o n s t メ ン バ 関 数 。
    };

    void f ( const MyClass& obj ) ; // パ ラ メ ー タ の c o n s t 参 照 渡 し 。

    void g ( ) {
      const double p i = 3.141592; // c o n s t ロ ー カ ル 変 数 。
    }




                                                                .   .    .   .   .   .
C++勉強会
  防衛的プログラミング




イディオムを利用



    イディオムとは?
    経験のあるプログラマが利用するソース・コードの共通の書き方。
    例えば、forループのイディオム。ループ条件にOpen-End(<)を利用することで、 要素数が0の
    時を特殊ケース扱いとしなくてもよい(sizeが0のときは、ループは 実行されない)。

    f o r ( i n t i = 0; i < s i z e ; ++ i ){
        ...
    }


         イディオムの利点:
               イディオムを知っているプログラマ間で、ソースコードの理解性が向上する。
               バグを発見しやすい。




                                                 .   .   .   .   .   .
C++勉強会
  参考情報




Topic



     1 オブジェクトによるリソースの管理。



     2 Interfaceの設計方法



     3 標準ライブラリ STLの活用



     4 防衛的プログラミング



     5 参考情報




                           .   .   .   .   .   .
C++勉強会
  参考情報




書籍




         The C++ Programming Language
         Effective C++
         More Effective C++
         Accelerated C++
         The C++ Standard Library: A Tutorial and Reference
         Effective STL
         IEEE Computer Society January 2012 "Software Development for
         Infrastructure"




                                                          .   .   .     .   .   .
C++勉強会
  参考情報




リンク




         cplusplus.com
         http://www.cplusplus.com/
         C++ FAQ
         http://www.parashift.com/c++-faq-lite/
         More C++ Idioms(C++イディオム集)
         http://en.wikibooks.org/wiki/More C%2B%2B Idioms
         Going Native 2012 Keynote by Bjarne Stroustrup: C++11 style
         http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/
         Keynote-Bjarne-Stroustrup-Cpp11-Style#+LTEX CLASS
                                                  A




                                                      .     .   .    .   .   .

Weitere ähnliche Inhalte

Was ist angesagt?

C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型信之 岩永
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0sunaemon
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)信之 岩永
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発Kazunori Hamamoto
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Keisuke Fukuda
 

Was ist angesagt? (19)

C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
More C++11
More C++11More C++11
More C++11
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
 

Andere mochten auch

C++でテスト駆動開発
C++でテスト駆動開発C++でテスト駆動開発
C++でテスト駆動開発Akineko Shimizu
 
シンギュラリティ以前
シンギュラリティ以前シンギュラリティ以前
シンギュラリティ以前Hiroshi Nakagawa
 
社内Slackを使ってなんか分析してみた話
社内Slackを使ってなんか分析してみた話社内Slackを使ってなんか分析してみた話
社内Slackを使ってなんか分析してみた話Serverworks Co.,Ltd.
 
全脳アーキテクチャ実現への長き道のりをいかに支えるのか
全脳アーキテクチャ実現への長き道のりをいかに支えるのか全脳アーキテクチャ実現への長き道のりをいかに支えるのか
全脳アーキテクチャ実現への長き道のりをいかに支えるのかドワンゴ 人工知能研究所
 
私はこうやってSlackを社内で流行らせました
私はこうやってSlackを社内で流行らせました私はこうやってSlackを社内で流行らせました
私はこうやってSlackを社内で流行らせましたNHN テコラス株式会社
 
Exponential Organizations - Why new organizations are 10x better, faster and ...
Exponential Organizations - Why new organizations are 10x better, faster and ...Exponential Organizations - Why new organizations are 10x better, faster and ...
Exponential Organizations - Why new organizations are 10x better, faster and ...Yuri van Geest
 

Andere mochten auch (9)

Move semantics
Move semanticsMove semantics
Move semantics
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
C++でテスト駆動開発
C++でテスト駆動開発C++でテスト駆動開発
C++でテスト駆動開発
 
シンギュラリティ以前
シンギュラリティ以前シンギュラリティ以前
シンギュラリティ以前
 
社内Slackを使ってなんか分析してみた話
社内Slackを使ってなんか分析してみた話社内Slackを使ってなんか分析してみた話
社内Slackを使ってなんか分析してみた話
 
全脳アーキテクチャ実現への長き道のりをいかに支えるのか
全脳アーキテクチャ実現への長き道のりをいかに支えるのか全脳アーキテクチャ実現への長き道のりをいかに支えるのか
全脳アーキテクチャ実現への長き道のりをいかに支えるのか
 
Emcpp item41
Emcpp item41Emcpp item41
Emcpp item41
 
私はこうやってSlackを社内で流行らせました
私はこうやってSlackを社内で流行らせました私はこうやってSlackを社内で流行らせました
私はこうやってSlackを社内で流行らせました
 
Exponential Organizations - Why new organizations are 10x better, faster and ...
Exponential Organizations - Why new organizations are 10x better, faster and ...Exponential Organizations - Why new organizations are 10x better, faster and ...
Exponential Organizations - Why new organizations are 10x better, faster and ...
 

Ähnlich wie C++勉強会

Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義JPCERT Coordination Center
 
画像処理でのPythonの利用
画像処理でのPythonの利用画像処理でのPythonの利用
画像処理でのPythonの利用Yasutomo Kawanishi
 
Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向1000 VICKY
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Yasutomo Kawanishi
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)洋史 東平
 
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFメディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFAtsushi Tadokoro
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRubyemasaka
 
Linq To Fun
Linq To FunLinq To Fun
Linq To Fundeflis
 
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門Kazunori Tatsuki
 
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWINHow to Make Own Framework built on OWIN
How to Make Own Framework built on OWINYoshifumi Kawai
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会Koichi Sakata
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
 ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイドEtsuji Nakai
 
Ruby Extended Library
Ruby Extended LibraryRuby Extended Library
Ruby Extended LibraryAkio Tajima
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsuNanha Park
 
PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法Yosuke Onoue
 

Ähnlich wie C++勉強会 (20)

Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義
 
画像処理でのPythonの利用
画像処理でのPythonの利用画像処理でのPythonの利用
画像処理でのPythonの利用
 
Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)
 
C#勉強会
C#勉強会C#勉強会
C#勉強会
 
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oFメディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRuby
 
Linq To Fun
Linq To FunLinq To Fun
Linq To Fun
 
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
 
20010901
2001090120010901
20010901
 
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWINHow to Make Own Framework built on OWIN
How to Make Own Framework built on OWIN
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
 ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
 
Ruby Extended Library
Ruby Extended LibraryRuby Extended Library
Ruby Extended Library
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsu
 
PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法PythonistaがOCamlを実用する方法
PythonistaがOCamlを実用する方法
 

C++勉強会

  • 1. C++勉強会 C++勉強会 Mitsutaka Takeda Company 07 March 2012 . . . . . .
  • 2. C++勉強会 Outline 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 3. C++勉強会 オブジェクトによるリソースの管理。 Topic 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 4. C++勉強会 オブジェクトによるリソースの管理。 リソースとは? Bjarne Stroustrup (Software Development for Infrastructure) `A resource is anything that has to be acquired and released after use.' . . . . . .
  • 5. C++勉強会 オブジェクトによるリソースの管理。 リソースの例 メモリ ファイル Mutex フォント ブラシ etc . . . . . .
  • 6. C++勉強会 オブジェクトによるリソースの管理。 リソース管理の問題点 使用後に解放しなければいけない。 解放しない(リークする)とリソースが不足する。例えばメモリ。 void f ( ) { MyClass * obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。 obj−>doSomething ( ) ; // リ ソ ー ス の 使 用 。 ... delete obj ; // リ ソ ー ス の 解 放 。 } 潜在不具合 リソースの使用中に例外を投げると、リソースが開放されない。 . . . . . .
  • 7. C++勉強会 オブジェクトによるリソースの管理。 リソースを確実に解放するため(その1) void f ( ) { MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。 try{ obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。 obj− >doSomething ( ) ; // リ ソ ー ス の 使 用 。 ... } catch ( std : : ba d al l o c& e ){ i f ( obj != NULL ) // リ ソ ー ス の 使 用 中 に 例 外 を 投 げ る か も 。 delete obj ; // d e l e t e を 省 略 で き な い こ と に 注 意 。 } catch ( . . . ) { delete obj ; // そ の 他 の 例 外 。 } delete obj ; } 保守性に問題。(バグを混入しやすい) 処理が複雑。例外の種類により処理の切り替えが必要。 ソースコードの変更に対して脆い。 コードが冗長(delete文が沢山ある)。 . . . . . .
  • 8. C++勉強会 オブジェクトによるリソースの管理。 ソースコードの変更に対する脆弱性 例えば、保守担当者が不具合対策として以下のような変更を加えた場合。 void f ( ) { MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。 try{ obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。 obj− >doSomething ( ) ; // リ ソ ー ス の 使 用 。 i f ( obj− >isSucceed ( ) ) r e t u r n ; // リ ソ ー ス ・ リ ー ク ! ! } catch ( std : : ba d al l o c& e ){ i f ( obj != NULL ) delete obj ; } catch ( . . . ) { delete obj ; } delete obj ; } . . . . . .
  • 9. C++勉強会 オブジェクトによるリソースの管理。 脆弱性に対する対策案(人に依存) コーディング規約(関数からのreturnは1箇所のみ等)による対策。 見逃したら? ソースコード・レビューで見逃さないようにする。 見逃したら? チェック・リストを作成して、レビュー時にチェックする。 見逃したら? ... 人はミスをするので、できるかぎりコンピュータに仕事をさせる。 マーフィーの法則 ``Anything that can go wrong will go wrong.'' . . . . . .
  • 10. C++勉強会 オブジェクトによるリソースの管理。 解決策(コンピュータに任せる) C++でのメモリ管理はオブジェクトに任せる。 RAII(Resource Acquisition Is Initialization)イディオム。 Javaやらガベージ・コレクション系の言語では無理!! . . . . . .
  • 11. C++勉強会 オブジェクトによるリソースの管理。 RAIIの基本的な考え方 ... 1 リソースの取得をオブジェクトの初期化(コンストラクタ)で行う。 ... 2 リソースの解放をオブジェクトの終了処理(デストラクタ)で行う。 C++の言語仕様で、コンストラクタが完了したオブジェクトの デストラクタの呼び出しが保証 されている。 MyClassのメモリ管理を行うクラス(スマート・ポインタの特殊ケース)。 c l a s s MyClassHandle{ public : MyClass * obj ; MyClassHandle ( ) { obj = new MyClass ( ) ; // コ ン ス ト ラ ク タ で リ ソ ー ス の 取 得 。 } ˜MyClassHandle ( ) { delete obj ; // デ ス ト ラ ク タ で リ ソ ー ス の 解 放 。 } }; . . . . . .
  • 12. C++勉強会 オブジェクトによるリソースの管理。 RAIIの適用(前) void f ( ) { MyClass * obj = NULL ; // リ ソ ー ス 用 変 数 を 宣 言 。 try{ obj = new MyClass ( ) ; // リ ソ ー ス の 取 得 。 obj− >doSomething ( ) ; // リ ソ ー ス の 使 用 。 ... } catch ( std : : ba d al l o c& e ){ i f ( obj != NULL ) delete obj ; } catch ( . . . ) { d e l t e obj ; } delete obj ; } 先程のコードにRAIIを適用すると。 . . . . . .
  • 13. C++勉強会 オブジェクトによるリソースの管理。 RAIIの適用(後) void f ( ) { // リ ソ ー ス 管 理 オ ブ ジ ェ ク ト を 生 成 ・ 初 期 化 ( = リ ソ ー ス の 取 得 ) MyClassHandle handle ; // リ ソ ー ス の 使 用 。 handle . obj−>doSomething ( ) ; ... }// f の 終 了 時 に デ ス ト ラ ク タ の 呼 び 出 し 。 注目点 適用後のコードではプログラマが自分でリソースの解放をしなくてもよいことに注目。 ハ ンドルがスコープをはずれると自動的にデストラクタが呼ばれてリソースが解放される。 たとえ例外が投げられても!! 適用前後のコード比較 コード量の減少 リソース・リークの防止 保守性の向上。コード変更後に処理の途中でreturnしてもリソース・リーク にならない。 . . . . . .
  • 14. C++勉強会 オブジェクトによるリソースの管理。 RAIIの応用 c l a s s Pen { public : HDC hdc ; HPEN new pen ; HGDIOBJ old pen ; Pen (HDC hdc , Color pen color ) : hdc ( hdc ) , old pen ( NULL){ new pen = CreatePen ( . . . ) ; // リ ソ ー ス の 取 得 。 i f ( new pen ) old pen = SelectObject ( hdc , new pen ) ; } ˜Pen ( ) { i f ( old pen ){ SelectObject ( hdc , old pen ) ; // 元 の ブ ラ シ に 戻 す 。 DeleteObject ( new pen ) ; // リ ソ ー ス の 解 放 。 } } }; . . . . . .
  • 15. C++勉強会 オブジェクトによるリソースの管理。 RAIIの応用 void draw ( ) { // 赤 色 の ペ ン を 作 成 。 r e d p e n オ ブ ジ ェ ク ト が 生 き て い る // ス コ ー プ で は 、 線 が 赤 色 に な る 。 r e d p e n オ ブ ジ ェ ク ト // が 破 壊 さ れ る と ペ ン の 色 は 、 元 の 色 に 戻 る 。 Pen red pen ( hdc , RED ) ; . . . // 描 画 。 } . . . . . .
  • 16. C++勉強会 オブジェクトによるリソースの管理。 RAIIを利用する際の注意点 ハンドル・クラスのコピー動作(コピー・コンスラクタと代入演算子)に注意!! MyClassHandle my obj1 ; MyClassHandle my obj2 ( my obj1 ) ; // コ ピ ー ・ コ ン ス ラ ク タ // リ ソ ー ス の 使 用 。 m y o b j 1 の o b j は ど う な る ? my obj2 . obj−>doSomething ( ) ; // void f ( i n t x ) ; 値 渡 し 。 i n t x = 3; f (x ); std : : cout < x < std : : endl ; // 3 と 表 示 。 < < // void g ( MyClassHandle obj ) 値 渡 し 。 MyClassHandle my obj3 ; g ( my obj3 ) ; // g の 呼 び 出 し 後 に m y o b j 3 の 状 態 は ? . . . . . .
  • 17. C++勉強会 オブジェクトによるリソースの管理。 RAIIのコピー動作 コピーを禁止 c l a s s MyClassHandle { private : // コ ピ ー ・ コ ン ス ラ ク タ と 代 入 演 算 子 を p r i v a t e 宣 言 。 // 実 装 は 必 要 な し 。 MyClassHandle ( const MyClassHandle & ) ; const MyClassHandle& operator =( const MyClassHandle & ) ; }; 参照カウントを利用してリソースを共有。(shared ptrの実装) . . . . . .
  • 18. C++勉強会 オブジェクトによるリソースの管理。 RAIIに関連してちょこっと脱線 リソースの取得はオブジェクトの初期化で行う。 オブジェクト初期化(生成)する時点で必要な 情報が全て揃っているのが理想。 できる限り初期化関数は避けましょう。 c l a s s BadClass{ public : void i n i t i a l i z e ( i n t x ) ; // 初 期 化 関 数 。 void doSomething ; }; BadClass obj ; // オ ブ ジ ェ ク ト の 生 成 ( 初 期 化 ) obj . i n i t i a l i z e ( 1 ) ; // 初 期 化 関 数 に よ る オ ブ ジ ェ ク ト の " 初 期 化 " obj . doSomething ( ) ; BadClass obj2 ; obj2 . doSoemthing ( ) ; // バ グ ! ! initializeの呼び出し前に他の関数 BadClass obj3 ; obj3 . i n i t i a l i z e ( 1 ) ; obj3 . i n i t i a l i z e ( 2 ) ; // 2回 初 期 化 関 数 を 呼 び 出 し て も 良 い ? . . . . . .
  • 19. C++勉強会 オブジェクトによるリソースの管理。 RAIIに関連してちょこっと脱線 初期化はコンストラクタで行う。 c l a s s BadClass{ public : BadClass ( i n t x ) ; void doSomething ( ) ; }; BadClass obj ( 1 ) ; obj . doSomething ( ) ; // 初 期 化 前 に 他 の 関 数 を 呼 び 出 せ な い 。 . . . . . .
  • 20. C++勉強会 Interfaceの設計方法 Topic 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 21. C++勉強会 Interfaceの設計方法 設計指針 Make interfaces easy to use correctly and hard to use incorrectly Effective C++ できるかぎり、コンパイラにエラーをチェックさせる。(マーフィーの法則) C++の型システムを利用する。 . . . . . .
  • 22. C++勉強会 Interfaceの設計方法 悪い例 その1 悪いインターフェイスの例。 パラメータの名前のみで、意味を区別しようとしている。 // 2点 間 の 距 離 を 計 算 。 i n t c a l c u l a t e D i s t a n c e ( i n t x0 , i n t y0 , i n t x1 , i n t y1 ) ; // ユ ー ザ 認 証 。 bool aut he n tic ate ( std : : s t r i n g password , std : : s t r i n g user name ) ; . . . . . .
  • 23. C++勉強会 Interfaceの設計方法 悪い例 その1 // 点 ( 1 , 3 ) と 点 ( 2 , 4 ) の 距 離 を 計 算 。 i n t distance = c a l c u l a t e D i s t a n c e ( 1 , 2 , 3 , 4 ) ; // バ グ ! ! i n t distance = c a l c u l a t e D i s t a n c e ( 1 , 3 , 2 , 4 ) ; // 正 し い 。 // ユ ー ザ を 認 証 。 std : : s t r i n g user name ( " user " ) ; std : : s t r i n g password ( " s e c r e t password " ) ; // バ グ ! ! ユ ー ザ 名 と パ ス ワ ー ド が 逆 。 bool i s a u t h e n t i c a t e d = auth ent icate ( user name , password ) ; // 正 し い 。 bool i s a u t h e n t i c a t e d = auth ent icate ( password , user name ) ; 使用方法を間違えても、誰も教えてくれない… . . . . . .
  • 24. C++勉強会 Interfaceの設計方法 改善 その1 小さなクラスを定義して利用する。 s t r u c t Point { Point ( i n t x , i n t y ) x (x) , y (y) { } int x ; int y ; } typedef unsinged i n t Distance ; // イ ン タ ー フ ェ イ ス ( 引 数 の 型 や 戻 り 値 の 型 ) を 見 た だ け で // 使 用 方 法 が 判 る 。 Distance c a l c u l a t e D i s t a n c e ( Point p1 , Point p2 ) ; . . . . . .
  • 25. C++勉強会 Interfaceの設計方法 改善 その2 typedef std : : s t r i n g Password ; typedef std : : s t r i n g User ; bool aut he n tic ate ( Password login password , User a user ) ; User my user name ( " user " ) ; Password my pass ( " s e c r e t password " ) ; bool i s a u t h e n t i c a t e d = auth ent icate ( my pass , my user name ) ; . . . . . .
  • 26. C++勉強会 Interfaceの設計方法 改善 その2 さらなる改善 typedefではコンパイル・エラーにはならないので注意。 User my user name ( " user " ) ; Password my pass ( " s e c r e t password " ) ; bool i s a u t h e n t i c a t e d = auth ent icate ( my user name , my password ) ; // バ グ ! ! コンパイラーにコードの正しさをチェックさせたいときは、クラスを利用する。 c l a s s User { ... }; c l a s s Password { ... }; 上記のコードはコンパイル・エラー。 . . . . . .
  • 27. C++勉強会 Interfaceの設計方法 脱線 typedefの効用 型名を短くできる。 typedef unsinged long long long MyType ; MyType my obj = . . . ; 型情報への参照を間接的にして局所化する。 typedef unsinged i n t Distance ; // ソ ー ス コ ー ド 中 の 色 々 な 場 所 で 、 Distance distance 1 = . . . ; ... Distance distance 100 = . . . ; Distanceに、unsinged intの最大値以上の値を保持する必要が。 typedefを使用していれ ば、変更箇所は1箇所ですむ。 型名にドキュメント情報(人が読むための情報として)。 . . . . . .
  • 28. C++勉強会 Interfaceの設計方法 悪い例 その2 リソースの取得と解放が別々の処理に分離されている。 MyClass * create ( ) ; void r e l e a s e ( MyClass * obj ) ; 問題点 クライアントがreleaseを呼び忘れたら? release以外の方法で、deleteされたら? . . . . . .
  • 29. C++勉強会 Interfaceの設計方法 改善 その3 生のポインタではなくスマートポインタを利用する。 boost : : shared ptr<MyClass> create ( ) ; もし、3rdパーティのライブラリで生のポインタを返すようにしている場合。 SomeonesClass * create ( ) ; void r e l e a s e ( SomeonesClass * obj ) ; shared ptrでは、解放の処理をカスタマイズできる。 // 第2 引 数 で 、 解 放 に 使 用 し た い 関 数 を 指 定 。 void f ( ) { boost : : shared ptr<SomeoneClass> p t r ( create ( ) , std : : p t r f u n ( r e l e a s e ) ) ; ptr−>doSomething ( ) ; }// 自 動 的 に 解 放 。 . . . . . .
  • 30. C++勉強会 標準ライブラリ STLの活用 Topic 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 31. C++勉強会 標準ライブラリ STLの活用 標準ライブラリを使用する利点 ...1 デバッグ済み(高い信頼性) ...2 他のプログラマに伝わりやすい(保守性) ...3 自動的に性能改善される可能性あり ...4 コードの記述量を減らすことができる バグの件数はソースコードのステップ数と相関 . . . . . .
  • 32. C++勉強会 標準ライブラリ STLの活用 STLの構造 container(データ構造) iterator algorithm IO 数値計算 internationalization 例外処理 . . . . . .
  • 33. C++勉強会 標準ライブラリ STLの活用 Container/Iterator/Algorithm Containerとは、複数のオブジェクトの集合を管理するためのコンポーネント。 Iteratorとは、Container中の要素にアクセスするためのコンポーネント。 Algorithmとは、Container中の要素を処理(検索、並びかえ)するためのコンポーネント。 . . . . . .
  • 34. C++勉強会 標準ライブラリ STLの活用 Container Sequence containers 順序付けられたcontainer。要素の順番はcontainerに追加した順番に依存。 vector deque list Associative containers 並びかえ済みcontainer。要素の追加時に指定した基準で要素を並びかえ。 set mutiset map multimap その他 Container Adapters(stack、queue、priority queue)、Cの配列。 . . . . . .
  • 35. C++勉強会 標準ライブラリ STLの活用 Iterator 反復子とよばれているContainer中の要素を指すオブジェクト。(Containerと Iteratorの関 係は、配列とポインタみたいなもの) Random access iterator Bidirectional iterator Forward iterator . . . . . .
  • 36. C++勉強会 標準ライブラリ STLの活用 Algorithm Container中の要素の範囲に特定の処理を行うためのライブラリ。 例: for each : Container中の全要素に対して処理を行う。 find : Container中から特定の要素を探す。 sort : Container中の要素を並びかえる。 . . . . . .
  • 37. C++勉強会 標準ライブラリ STLの活用 使用例 typedef std : : vector<i n t> numbers ; std : : vector<i n t> createNumbers ( ) { std : : vector<i n t> numbers ; f o r ( i n t i = 0; i < 10; ++ i ){ numbers . push back ( getRandomNumber ( ) ) ; } // 昇 順 に 並 べ 替 え 。 s o r t は デ フ ォ ル ト で (<) を 利 用 し て 並 べ 替 え る 。 std : : s o r t ( numbers . begin ( ) , numbers . end ( ) ) ; // 降 順 に 並 べ 替 え 。 g r e a t e r 関 数 を 利 用 し て 並 べ 替 え 。 std : : s o r t ( numbers . begin ( ) , numbers . end ( ) , greater<i n t > ( ) ) ; } . . . . . .
  • 38. C++勉強会 標準ライブラリ STLの活用 関数オブジェクト operator()をメンバ関数を保持するオブジェクト。STLを拡張するために利用する。 s t r u c t MyGreater{ bool operator ( ) ( i n t x , i n t y ) { return x > y ; } }; // 降 順 に 並 べ 替 え 。 M y G r e a t e r 関 数 オ ブ ジ ェ ク ト を 利 用 し て 並 べ 替 え 。 std : : s o r t ( numbers . begin ( ) , numbers . end ( ) , MyGreater ( ) ) ; . . . . . .
  • 39. C++勉強会 標準ライブラリ STLの活用 コーディング without STL(電話帳 氏名と電話番号を管理するプログラム) const i n t MAX SIZE(1000); Name *names = new Name[ MAX SIZE ] ; PhoneNumber phone numbers = new PhoneNumber [ MAX SIZE ] ; unsigned i n t s i z e = 0; void addRecord (Name name , PhoneNumber phone number ){ i f ( s i z e >= MAX SIZE ){ // 最 大 長 を 越 え て い る た め メ モ リ の 確 保 と デ ー タ の コ ピ ー 。 Name * new name data = new Name[2 * s i z e ] ; PhoneNumber * new phone number data = new PhoneNumber[2 * s i z e ] ; f o r ( i n t i = 0; i < s i z e ; ++ i ){ new name data [ i ] = names [ i ] ; new phone number data [ i ] = phone numbers [ i ] } Name *tmp1 = names ; PhoneNumber *tmp2 = phone numbers ; names = new name data ; phone numbers = new phone number data ; delete [ ] tmp1 ; delete [ ] tmp2 ; } // レ コ ー ド を 追 加 。 names [ s i z e ] = name ; phone numbers [ s i z e ] = phone number ; ++ s i z e ; } void sortPhoneBook (Name *names , PhoneNumber * phone numbers ){ . . . } . . . . . .
  • 40. C++勉強会 標準ライブラリ STLの活用 コーディング with STL typedef std : : pair<Name, PhoneNumber> RecordType ; typedef std : : vector<RecordType> PhoneBook ; PhoneBook my phone book ; void addRecord (Name name , PhoneNumber phone number ) { my phone book . push back ( std : : make pair ( name , phone number ) ) ; } void sortPhoneBook ( PhoneBook& phone book ){ // M y C r i t e r i a l は 自 分 が ソ ー ト し た い 基 準 を 表 現 す る 関 数 オ ブ ジ ェ ク ト 。 std : : s o r t ( phone book . begin ( ) , phone book . end ( ) , M y C r i t e r i a ( ) ) ; } . . . . . .
  • 41. C++勉強会 標準ライブラリ STLの活用 STLを利用するさいにも色々な注意点が。 それは次の機会に。 . . . . . .
  • 42. C++勉強会 防衛的プログラミング Topic 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 43. C++勉強会 防衛的プログラミング 変数のスコープを最小限に // ル ー プ 変 数 ( i ) は 、 f o r の 初 期 化 ブ ロ ッ ク で 。 f o r ( i n t i = 0; i < N; ++ i ) { ... } void bad ( ) { // 関 数 の 頭 で 全 変 数 を 宣 言 。 i n t x = 0; std : : s t r i n g s t r ( "My name i s " ) ; ... s t r += " Takeda " ; ... ++x ; } void b e t t e r ( ) { ... std : : s t r i n g s t r ( "My name i s " ) ; s t r += " Takeda " ; ... i n t x = 0; ++x ; } void best ( ) { ... const std : : s t r i n g s t r ( "My name i s Takeda " ) ; ... i n t x = 1; . . . . . .
  • 44. C++勉強会 防衛的プログラミング constの活用 できる限りconstを使用する。 c l a s s MyClass { public : void doSomething ( ) const ; // c o n s t メ ン バ 関 数 。 }; void f ( const MyClass& obj ) ; // パ ラ メ ー タ の c o n s t 参 照 渡 し 。 void g ( ) { const double p i = 3.141592; // c o n s t ロ ー カ ル 変 数 。 } . . . . . .
  • 45. C++勉強会 防衛的プログラミング イディオムを利用 イディオムとは? 経験のあるプログラマが利用するソース・コードの共通の書き方。 例えば、forループのイディオム。ループ条件にOpen-End(<)を利用することで、 要素数が0の 時を特殊ケース扱いとしなくてもよい(sizeが0のときは、ループは 実行されない)。 f o r ( i n t i = 0; i < s i z e ; ++ i ){ ... } イディオムの利点: イディオムを知っているプログラマ間で、ソースコードの理解性が向上する。 バグを発見しやすい。 . . . . . .
  • 46. C++勉強会 参考情報 Topic 1 オブジェクトによるリソースの管理。 2 Interfaceの設計方法 3 標準ライブラリ STLの活用 4 防衛的プログラミング 5 参考情報 . . . . . .
  • 47. C++勉強会 参考情報 書籍 The C++ Programming Language Effective C++ More Effective C++ Accelerated C++ The C++ Standard Library: A Tutorial and Reference Effective STL IEEE Computer Society January 2012 "Software Development for Infrastructure" . . . . . .
  • 48. C++勉強会 参考情報 リンク cplusplus.com http://www.cplusplus.com/ C++ FAQ http://www.parashift.com/c++-faq-lite/ More C++ Idioms(C++イディオム集) http://en.wikibooks.org/wiki/More C%2B%2B Idioms Going Native 2012 Keynote by Bjarne Stroustrup: C++11 style http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/ Keynote-Bjarne-Stroustrup-Cpp11-Style#+LTEX CLASS A . . . . . .