C++ の型とキャスト 解答ページ | Programming Place Plus C++編【言語解説】 第7章

トップページC++編

C++編で扱っている C++ は 2003年に登場した C++03 という、とても古いバージョンのものです。C++ はその後、C++11 -> C++14 -> C++17 -> C++20 -> C++23 と更新されています。
なかでも C++11 での更新は非常に大きなものであり、これから C++ の学習を始めるのなら、C++11 よりも古いバージョンを対象にするべきではありません。特に事情がないなら、新しい C++ を学んでください。 当サイトでは、C++14 をベースにした新C++編を作成中です。

問題①

問題① 次の各変換は、static_cast、const_cast、reinterpret_cast、C言語形式のキャスト、キャストは不要、のいずれで行えるか答えてください。

  1. long → short
  2. bool → int
  3. int* → int
  4. const char* → char*
  5. struct MyData* → void*
  6. struct MyData* → const struct MyData*
  7. void* → struct MyData*
  8. const float* → int*
  9. bool (*f)(int) → bool (*f)(const char*)


1. long → short

暗黙的に変換できますが、大きさが小さくなると元の値が表現できない可能性があるため、ほとんどのコンパイラでは警告が出ます。static_cast か、C言語形式のキャストで、問題がないことを明示できます。C++ では static_cast を使いましょう。

2. bool → int

キャストは不要です。true なら 1 に、false なら 0 になります。

3. int* → int

reinterpret_cast か、C言語形式のキャストが使えます。C++ では reinterpret_cast を使いましょう。

4. const char* → char*

const_cast か、C言語形式のキャストが使えます。C++ では const_cast を使いましょう。

5. struct MyData* → void*

あるポインタ型から void*型へは、暗黙的に変換できますから、キャストは不要です。

6. struct MyData* → const struct MyData*

const修飾子を付ける方向へは、暗黙的に変換できますから、キャストは不要です。

7. void* → struct MyData*

static_cast、reinterpret_cast、C言語形式のキャストのいずれでも可能です。C++ では static_cast を使いましょう。

8. const float* → int*

C言語形式のキャストを使えば一気に変換できますが、C++ では static_cast と const_cast を併用して書くべきです。

int* p2 = static_cast<int*>(static_cast<void*>(const_cast<float*>(f)));

9. bool (*f)(int) → bool (*f)(const char*)

reinterpret_cast か、C言語形式のキャストが使えます。C++ では static_cast を使いましょう。

書き方が分かりにくいので、例を挙げておきます。

#include <iostream>

bool func(int a);

int main()
{
    bool (*p1)(int) = func;
//    bool (*p2)(const char*) = (bool (*)(const char*))p1;
    bool (*p2)(const char*) = static_cast<bool (*)(const char*)>(static_cast<void*>(p1));

    std::cout << p2("abc") << std::endl;
}

bool func(int a)
{
    return true;
}

実際のところ、関数ポインタの型が必要ならば、typedef した別名を用意する方が良いでしょう。

#include <iostream>

typedef bool (*func_int)(int);
typedef bool (*func_cchar_ptr)(const char*);

bool func(int a);

int main()
{
    func_int p1 = func;
//    func_cchar_ptr p2 = (func_cchar_ptr)p1;
    func_cchar_ptr p2 = static_cast<func_cchar_ptr>(static_cast<void*>(p1));

    std::cout << p2("abc") << std::endl;
}

bool func(int a)
{
    return true;
}

この例では、func関数内で引数a を使っていないので、特に何事もなく実行できますが、使っているようだと、int型の引数を想定している関数に、const char*型の値を渡すことになるので危険です。


参考リンク


更新履歴

’2014/2/26 ポインタ型同士のキャストについて、記述を改めた。

’2014/1/18 新規作成。



第7章のメインページへ

C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る