トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
C++
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索

___

■ cast(キャスト)



    型変換
  // int -> double
  double dval = (double)ival;

  // 
  long -> int *
  int *iptr = (int *)lval;

  
      reinterpret_cast : ptr 同士の変換 | ptr < -> int( ptr アドレスは不変 )
           

___

■ reinterpret_cast

互換性のないポインタ同士のキャストに利用する。 reinterpret_cast は偽者の型でもキャストできてしまう。 安全性という視点では使うのは良くない。
    // int * -> long *
    lptr = reinterpret_cast< lptr>( iptr );
dynamic_cast : CBase から CDerived への型保障キャスト (逆)? POINT upcast : CDerived -> CBase downcast : CBase -> CDerived POINT cpp スタイルのキャストを利用することで, キャストの意図を明確にする WARNING キャストは 飽くまで [ 型がこうである ] と コンパイラに言い聞かせるだけ。 ( 保障は一切ない ) だから Cast は最低限にするべき ( C++ ならば Template で代用すること )
    void onClick( Gui *gui ) {
      
      Button *b = reinterpret_cast<  Button >( gui );
    }
POINT アセンブラでは型という概念がない アドレスを指定して, Data を Add, するだけ 中身( アドレスの指す先の bit 列 が Integer )を意味するかどうかは プログラマが責任ををもってしていた しかしそれば手間で、中身を間違うという事故があったため、型というルールができた。
    // キャストの内容によってメモリ上の値が変わることも、不変な場合もある
    // VisualStudio のメモリウィンドウで確認できる。

    int i = 128;   // MEM IMG [ 0x 80 00 00 00 ]
    int i2 = i;    // MEM IMG [ 0x 80 00 00 00 ]
    float f = i;   // MEM IMG [ 0x 00 00 00 43 ]  // ここが43となる点に注意
結論 アドレス( という数値 )を格納する場合は, 変更されない. なぜなら adr の指す先の Object をこう読んでね とい言うようなもの. 数値型の場合は, 型によって表現方法が異なるので, bit 列が変更される. base obj を derive obj の ptr に cast して操作すれば,問題があることを意識する
___

■ const_cast

const, volatile 外し
  // cint * -> int *
  iptr = const_cast< int *>ciptr;
  // cint -> int 
  ival = const_cast< int>cival; // ERR( ptr 以外はだめ ? )
___

■ static_cast

DESC [ 暗黙の型変換 ]がある場合のみ変換できる。 [ 安全な型変換 ] 暗黙の型変換があれば変換 安全な cast を意味するので, c_style_cast より積極的に利用するべき OK
    // void * < -> any *  
         -> down cast の場合, 派生先の領域にアクセスするのは危険かも

    // upcast
    Bcls *p = static_cast< Bcls *>( pDcls );

    // const をつける
    int p = 10;
    const int cp = static_cast<  const int >( p );
    cp = 20;  // error: assignment of read-only variable `cp'

      static_cast: 

  int -> long
  lval = static_cast< long>(ival); // OK
  void *-> int
  ival = static_cast< void *>ival; // ERROR


ERROR Foo *p = static_cast< Foo *>( pBar ); // 継承関係のない cls 3. dynamic_cast ptr が指す obj の型を取得( obj がどの mem func を support しているか確認という意味 ) WARNING polymorphic cls のみ( ∵ vtbl 必要 ) 4. reinterpret_cast 指定された型に[ 読み替える ]のみ -> 無理やり別の型に変換する.
      void *p = reinterpret_cast< void *>( &fooObj );  // ptr ads は不変
WARNING 多重継承していると 問題が起きる POINT
    // コンパイルエラーで出力される内容が正しい型変換を意味する
  MSG:: c style cast || static_cast が必要です
___

■ dynamic_cast

POINT オブジェクトがあるインターフェイスをサポートするか調べるときに使う。 派生クラスから基底クラスへダウンキャストする時に使う。 [ ptr がさす obj の型を取得 ] として考えれば OK dynamic_cast が使用できるのは, 仮想メンバ関数をもつ場合
    Base *p = new Derive();

    
    Derive *d = dynamic_cast< Derive *>(p);


    Another *p = new Another();

    // キャストできない場合は NULL を返す
    Derive *d = dynamic_cast< Derive *>(p);
DESC base -> derive ptr への cast constructor 時に dynamic_cast< derive *>(this) としても 変換は不可能 construct 時に 処理をわけることは不可能 WARNING class が virtual 関数を含む必要あり == polymorphic class の必要あり( compile err )

NINJAIDX 12