キャスト

スポンサーリンク

旧式のキャスト

C から引き継がれた旧式のキャストは,C 形式,関数形式の 2 つの形式で書けます。

double p = 3.14;
int m = (int) p;  // C 形式
int n = int(p);   // 関数形式

名前付きキャスト

C++ では,次の 4 つの名前付きキャスト演算子が導入されました。

  • 静的キャスト (static_cast)
  • 動的キャスト (dynamic_cast)
  • const キャスト (const_cast)
  • 再解釈キャスト (reinterpret_cast)

これらのキャストは,キャスト名<型名>(式) の形で用います。
例えば,double から int へのキャストは static_cast を用いて次のように書けます。

double p = 3.14;
int n = static_cast<int>(p);

静的キャスト (static_cast)

静的キャストは (static_cast) は,他の 3 つの強力なキャストを必要としない,比較的安全な変換に用いられます。
具体的には,int から short への変換,void* から int* への変換などに用いられます。

void* p = NULL;
int* q = static_cast<int*>(p);

動的キャスト (dynamic_cast)

Base が基底クラス,Derived がその派生クラスのとき,次のようなプログラムが書けます。
これは Drived* から Base* への変換を行うものであり,アップキャストと呼ばれます。

Derived* dp = new Derived();
Base* bp = dp;   // アップキャスト

動的キャスト (dynamic_cast) は,これの逆である Base* から Derived* への変換,すなわちダウンキャストを行います。
名前の通り,プログラム実行時に変換を行います。

ポインタ型への変換では,変換に失敗すると NULL を評価結果とします。
参照型への変換では,変換に失敗すると bad_cast 例外が投げられます。

次に示すプログラムは,dynamic_cast を用いたプログラムの例です。

#include <iostream>

class Base
{
public:
    virtual ~Base() { }
};

class Derived : public Base
{
};

int main()
{
    Base* bp = new Derived();
    Derived* dp = dynamic_cast<Derived*>(bp);

    if (dp) std::cout << "dynamic_cast succeeded" << std::endl;
    else std::cout << "dynamic_cast failed" << std::endl;

    delete bp;
}
<b>[出力]</b>
dynamic_cast succeeded

次の例では,bp の指すオブジェクトが Base 型であるため,変換に失敗します。

int main()
{
    Base* bp = new Base();
    Derived* dp = dynamic_cast<Derived*>(bp);

    if (dp) std::cout << "dynamic_cast succeeded" << std::endl;
    else std::cout << "dynamic_cast failed" << std::endl;

    delete bp;
}
<b>[出力]</b>
dynamic_cast failed

const キャスト (const_cast)

const キャスト (const_cast) は,const や volatile を除去するために用います。

const int* p;
int* q = const_cast<int*>(p);

再解釈キャスト (reinterpret_cast)

再解釈キャスト (reinterpret_cast) は,互換性のないポインタ型同士の変換や,整数型とポインタ型との間の変換に用います。

#include <iostream>

int main()
{
    char cp[] = { 0x89, 0xAB, 0xCD, 0xEF };
    int* ip = reinterpret_cast<int*>(cp);
    std::cout << std::hex << *ip << std::endl;
}
<b>[出力]</b>
efcdab89

この出力結果から,実行環境のエンディアンはリトルエンディアンであることがわかります。

スポンサーリンク