型変換

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

型変換(かたへんかん)とはプログラムにおいて、あるデータ型を他のデータ型に変換することである。

分類[編集]

暗黙の型変換と明示的型変換[編集]

暗黙の型変換は、明示的に指定しなくてもコンパイラの判断によって自動的に行われる型変換である。逆に、明示的に指定して行う型変換を明示的型変換という。

暗黙の型変換では、たとえばある式の中に複数の型の変数がある場合、すべての変数を最も上位の型に変換する。

double  d;
long    l;
int     i;
// ...
if (d > i)      d = i;
if (i > l)      l = i;
if (d == l)     d *= 2;

このC言語のコードでは、dliは異なったデータ型をもっているので、すべての演算は自動的に同じ型に変換された後に行われる。

暗黙の型変換には注意しなければならないこともある。たとえばdouble型(浮動小数点数)の値をint型(整数型)の変数に代入する場合、小数点以下の端数があったり、元の値がint型で表現できる範囲を超えていたりすると、情報の一部が失われてしまう(C言語ではそのような変換を許している)。

組込みの型変換とユーザ定義の型変換[編集]

基本的な型変換(整数どうしの変換や、整数と浮動小数点数との間の変換など)は、多くの処理系でコンパイラまたはプロセッサ内に既に定義されている。一方、ある型から別の型への変換をユーザが定義できる言語もある。

例えばC++では、ユーザ定義型の中に変換元の型を一つだけとるコンストラクタを定義すれば、ユーザ定義の暗黙の型変換が定義できる。コンストラクタにexplicit修飾子をつけると暗黙の型変換が許されなくなり、明示的型変換が必要となる。

class Class1 { };
class Class2 {
public:
  explicit Class2(Class1 c1) { ... }
};

void test() {
  Class1 c1;
  Class2 c2 = (Class2)c1;
  // explicit修飾子がなければ Class2 c2 = c1; でよい
}

ここで、Class1Class2の間には継承関係がないにもかかわらず代入ができている。これはClass1からコンストラクタを通してClass2に型変換されるからである。

なお、上の例では型変換の構文をとってはいるが、実際の処理としてはc1はコンストラクタへの引数として渡されている。そのため、本来必要のないc1のコピーが生成される。これを避けるために、変換元の型がユーザ定義型である場合には、通常は引数を参照として渡す。また、型変換という操作の意味を考えれば、変換元のインスタンスに変更を加えるということはあり得ないので、通常は引数にconst修飾子をつけて変更不可とする。結局、コンストラクタの宣言はexplicit Class2(const Class1& c1) { ... } のように書くことが多い。

キャストとその分類[編集]

C言語とその流れにある言語では、キャスト演算子によるキャスト式により、式の右辺値を指定された型に型変換する。この構文をキャストと呼ぶ。C言語のキャスト演算子は、型名を括弧で囲んだ、(int) のようなもので、目的の式に前置する。

アップキャスト[編集]

あるクラスBaseと、Baseから派生したクラスDerivedがあるとする。アップキャストとは、派生クラスから基底クラスへの型変換、すなわちDerivedのインスタンスをBaseに変換する操作である。「DerivedのインスタンスはBaseのインスタンスである」ことは保証されているので、一般的にはこの変換は安全である。そのため、多くの言語において、これは暗黙に行うことができる。

ただし、C++において多重継承のクラスのアップキャストが安全でないとされる環境では、dynamic_castを使うことが推奨される。

ダウンキャスト[編集]

ダウンキャストはアップキャストの逆で、基底クラスから派生クラスへの型変換、すなわちBaseのインスタンスをDerivedに変換する操作である。Baseのインスタンスは必ずしもDerivedのインスタンスとは限らないので、この変換は一般に安全ではなく、エラーが発生する可能性がある。そのため、多くの言語では明示的な構文が必要である。

C++では、ダウンキャストのためにdynamic_castという特別な構文が用意されている。この構文では、変換が失敗すると結果としてNULLが返る。

クロスキャスト[編集]

あるクラスDerivedが、二つの基底クラスBase1Base2を多重継承しているとする。このとき、例えばBase1からBase2のように基底クラスどうしの間で型変換することをクロスキャストという。変換する対象がDerivedのインスタンスであればキャストは成功するが、それは実行時にならないと分からないので、ダウンキャストと同様に安全な型変換ではない。

C++では、ダウンキャストと同じ構文dynamic_castでクロスキャストが行える。

静的キャスト[編集]

整数どうしの型変換や整数と浮動小数点数との間の型変換などの、ごく一般的な型変換。

関連項目[編集]