アップキャストとダウンキャスト

Baseクラスと、それを継承したExtendクラスがあるとする。

classes.png
Fig. 1: BaseクラスとExtendクラス

図のように?、ExtendクラスはBaseクラスを継承してちょっと要素(メンバ変数やメンバ関数)が増えている。
これらの変数(=インスタンスを考える)

Base iBase;
Extend iExt;
instance.png
Fig. 2: BaseクラスとExtendクラスのインスタンス

アップキャスト

実際には多分、以下のような感じになる。
このときに、両方のクラスBaseとExtendは、どちらも基本部分のBaseを含んでいるのはご存じだと思う。
継承関係のあるクラス間では、これらのBase部分を基準に、型変換を行うことができる。
そんで、継承先(でかいほう)からベースクラス(小さいほう)へキャスト(型変換)することをアップキャストといいます。

"main.cpp"
#include <iostream>
 
class Base
{
public:
	Base():x_(0),y_(0){}; //インライン関数
	Base(int _x,int _y):x_(_x),y_(_y){};
	int x_;
	int y_;
};
class Extend:public Base
{
public:
	Extend():Base(),z_(0){}
	Extend(int _x,int _y,int _z):Base(_x,_y),z_(_z){}
	int z_;
};
 
using namespace std;
int main() {
	Extend iExt(2,3,4);
	cout << "(x, y, z) = " << iExt.x_ << ", " << iExt.y_ << ", " << iExt.z_ << endl;
	Base iDown_casted = (Base)iExt; //アップキャスト
	cout << "(x, y, z) = " << iDown_casted.x_ << ", " << iDown_casted.y_ << ", " << iDown_casted.z_ << endl;
}

この例では、 int x,y,zの値を持っているExtendクラスのインスタンス(iExt)をBaseクラスに(Base)を書くことで強制的に型変換している。
この型変換によって、インスタンスは完全にBaseクラスに変換されてしまうため、int zのメンバは失われてしまっている。

したがって、iDown_casted.z_を表示しようとすると、コンパイルエラーになる。 メンバ変数はBaseクラスの持つx,yだけになり、以下のようにすると正常に動くようになる。(z表示してないだけ)

"main.cpp"
	Base down_casted = (Base)iExt;
	//cout << "(x, y, z) = " << down_casted.x_ << ", " << down_casted.y_ << ", " << down_casted.z_ << endl;
	//↑int zがなくなるから、コンパイルエラーになるよ
	cout << "(x, y) = " << down_casted.x_ << ", " << down_casted.y_ << endl;