第4章 参照先は何もなし?

 ポインタ。それはアドレスを入れる変数です。その型名は、参照先の型に * をつけたものですね。では、void に * をつけるとどうなるのでしょうか。今回は、その void* に関するお話です。


 では、今回の要点です。


 では、いってみましょう。


 さて、ポインタ型は参照先の型に * をつけたものです。好奇心の強い人は void に * をつけるとどうなるのか、と考えたことがあるかもしれません。

 参照先の型が void ? それって参照できるんでしょうかね? できないとなると、こんなポインタは作れないんでしょうかね?

 答は、やっぱりプログラムを作って確かめてみましょう。

プログラムコンパイルエラー
// VoidPtr1.cpp
#include <iostream.h>

int main()
{
    char   c = 1;
    int    i = 2;
    double d = 3;
    void*  p;

    p = &c;
    cout << *p << endl;

    p = &i;
    cout << *p << endl;

    p = &d;
    cout << *p << endl;

    return 0;
}











VoidPtr1.cpp(12) : error C2100: 間接指定演算子 (*) の使い方が不正です。


VoidPtr1.cpp(15) : error C2100: 間接指定演算子 (*) の使い方が不正です。


VoidPtr1.cpp(18) : error C2100: 間接指定演算子 (*) の使い方が不正です。


 コンパイルエラーは出ましたが、何と、ポインタの宣言とポインタへの代入についてのエラーは出ていません。

 ということは、void ポインタは作れるということになります。そして、上の様子からいくと void ポインタへはキャストなしでいろいろなポインタを代入できるみたいです。

 しかし、void ポインタを使った参照は行えないようです。


 void ポインタは、この「キャストなしでいろいろなポインタを代入できる」というのが一番の特徴です。void ポインタはまさにこのために使います。

 しかし、参照できないのはどうしたものでしょうか。参照できないポインタなんて、その存在価値のほとんどをなくしてしまっているも同然です。

 と、実はこの解決は非常に簡単です。キャストすればいいのです。

p = &c;
cout << *(char*)p << endl;

p = &i;
cout << *(int*)p << endl;

p = &d;
cout << *(double*)p << endl;

 このように、キャストしてしまえば何の問題もなく参照できるのです。

 void ポインタから他のポインタへの代入も同じで、そのままでは代入できません。キャストして初めて他のポインタへ代入できるようになります。


 void ポインタはよく引数で使います。

 アドレスを受け取るときに型を不問にしたいときがあるでしょう。例えば fwrite(第1部第55章参照)の第1引数などがそうです。

 fwrite はファイルにデータを書き込む関数です。第1引数にはデータのアドレスを指定するのですが、この型を char* にしていると int 型の変数の内容を書き込みたいときなどに不便です。かといって、int* にしたからといってやはり char 型の変数の内容を書き込みたいときなどに不便です。

 そこで、これを void ポインタにしておいてやると、キャストなしでどんな型のデータでも指定することができるのです。void ポインタはこういった利用法以外にはあまり使いません。


 では、今回の要点です。


 では、次回まで。


第3章 コンパイル済 | 第5章 飛んでいきな

Last update was done on 2000.8.4

この講座の著作権はロベールが保有しています