キャストをミスったときのエラー
初心者丸出しの記事を書くよー
#include <iostream> #include <cstdio> using namespace std; class Man{ public: int height; int weight; public: Man(int h_, int w_):height(h_), weight(w_){ } string toString(){ char temp[100]; sprintf(temp, "Man<h=%d, w=%d>", height, weight); return string(temp); } }; class Fighter: public Man{ protected: int strength; public: Fighter(int h_, int w_, int s_):Man(h_, w_), strength(s_) { } string toString(){ char temp[100]; sprintf(temp, "Fighter<h=%d, w=%d, s=%d>", height, weight, strength); return string(temp); } }; int main(){ Man a = Man(160, 50); cout << a.toString() << endl; Fighter b = Fighter(180, 90, 100); cout << b.toString() << endl; /* pointer */ cout << "*pointer test" << endl; Man* p = &b; cout << p->toString() << endl; cout << ((Fighter*)p)->toString() << endl; /* reference */ cout << "*reference" << endl; Man& r = b; cout << r.toString() << endl; cout << ((Fighter&)r).toString() << endl; /* copy */ cout << "*copy" << endl; Man m = b; cout << m.toString() << endl; cout << ((Fighter)m).toString() << endl; /* 56行目。エラー起こるよ! */ return 0; }
オブジェクト・スライシングの実験をしてたんだけど、この56行目でこんなエラーが出ます。(gccのg++の3を使ってます。)
slicing.cpp: In function `int main()': slicing.cpp:56: error: no matching function for call to `Fighter::Fighter(Man&)' slicing.cpp:21: note: candidates are: Fighter::Fighter(const Fighter&) slicing.cpp:25: note: Fighter::Fighter(int, int, int)
そういえば、無効なキャスト*1をしたときに「キャストできないよ!」って言ってくれればいいのに、なんで「コンストラクタが無いぞっ!」とかかわいく言ってくるのかなーと疑問に思っていたのですが、そういえば以前詳説C++*2の、演算子オーバーロードのあたりで、キャスト演算子の話のときにそんな話が出たので復習してみた。
どうも、「型変換コンストラクタ」とか言うらしい。これは、1つの引数で呼べるコンストラクタのことだそうで、例えばそのコンストラクタの1つの引数がX型で、コンストラクタを定義しているクラスがTなら、暗黙、明示どちらでもX→Tの変換ができるらしい。というわけでやってみた。
#include <iostream> #include <cstdio> using namespace std; class Man{ public: int height; int weight; public: Man(int h_, int w_):height(h_), weight(w_){ } string toString(){ char temp[100]; sprintf(temp, "Man<h=%d, w=%d>", height, weight); return string(temp); } }; class Fighter: public Man{ protected: int strength; public: Fighter(int h_, int w_, int s_):Man(h_, w_), strength(s_) { } Fighter(Man& m_):Man(m_.height, m_.weight){ strength = 0; } string toString(){ char temp[100]; sprintf(temp, "Fighter<h=%d, w=%d, s=%d>", height, weight, strength); return string(temp); } }; int main(){ Man a = Man(160, 50); cout << a.toString() << endl; Fighter b = Fighter(180, 90, 100); cout << b.toString() << endl; /* pointer */ cout << "*pointer test" << endl; Man* p = &b; cout << p->toString() << endl; cout << ((Fighter*)p)->toString() << endl; /* reference */ cout << "*reference" << endl; Man& r = b; cout << r.toString() << endl; cout << ((Fighter&)r).toString() << endl; /* copy */ cout << "*copy" << endl; Man m = b; cout << m.toString() << endl; cout << ((Fighter)m).toString() << endl; /* エラー起こらないよ!でもstrengthは0だよ!Fighter涙目! */ return 0; }
実験終わり。夏休みも終わり。