C++の新しいキャスト(の応用?)
C++ではstatic_cast
、const_cast
、dynamic_cast
、そしてreinterpret_cast
といった4つのキャストによりコードをよりわかりやすくし、さらにキャスト部分の検索もしやすくなっている。
さらにテンプレートを使用した場合と同じイディオムを使用しており、拡張することも容易である。たとえばこんな感じに独自のキャストを定義でき、さらにそれはC++のキャストと同じ形式で使用できる。
#include
<exception>
#include
<string>
class
IllegalCastException :public
std::exception {
private
:
std::string msg;
public
:
IllegalCastException()throw
() : msg("cast error."
) {}
~IllegalCastException() {}
const
char
* what()const
throw
() {
return
msg.c_str();
}
};
// 独自のキャストの定義
template
<class
T,class
S>
inline
T dynamic_cast_with_err(S* src) {
T result =dynamic_cast
<T>(src);
if
(result ==0
)throw
IllegalCastException();
return
result;
}
class
Base {
public
:
virtual
~Base() {}
};
class
Extend :public
Base {
};
class
Hoge {
};
#include
<iostream>
int
main() {
Base* b =new
Extend;
try
{
std::cout <<"Base->Extend..."
;
// ここで独自のキャストを使用する
Extend* e = dynamic_cast_with_err<Extend*>(b);
std::cout <<"success."
<< std::endl;std::cout <<
"Base->Hoge..."
;
Hoge* h = dynamic_cast_with_err<Hoge*>(b);
std::cout <<"success."
<< std::endl;
}catch
(IllegalCastException& e) {
std::cout << e.what() << std::endl;
}
}
Boostではこのようなキャストの他に、数値から文字列に、文字列から数値に変換する関数もこのように定義されており、C++のキャストと同じ形式で使用できる。