10進数と16進数の整数クラス(実装編) [プログラミング]
(前回までのあらすじ)
10進数で書かれた整数を扱うクラスがありました。
10進数と16進数の両方を処理できる様に拡張することになりました。
typedef MultiRadixValue<DecValue, HexValue> DecHexValue; int main() { char buff[100]; std::cin >> buff; DecHexValue value(buff); if (value.is_valid()) { std::cout << value.get_int() * 2 << "\n"; } else { std::cout << "数値ではない\n"; } return 0; } typedef MultiRadixValue<DecValue, HexValue, OctValue> DecHexOctValue;
そして、色々と考えた結果、こんな感じに使えるクラスが良かろうという結論になりました。
(あらすじ終わり)
でもって、これがその実装。
class ValueInt { protected: std::string value_str_; public: ValueInt(const char* value_str) : value_str_(value_str) { } virtual ~ValueInt() { } virtual bool is_valid() const = 0; virtual int get_int() const = 0; }; template <int RADIX> class RadixValueInt : public ValueInt { public: RadixValueInt(const char* value_str) : ValueInt(value_str) { } bool is_valid() const { char* end; strtol(value_str_.c_str(), &end, RADIX); return *end == '\0'; } int get_int() const { char* end; const int value = strtol(value_str_.c_str(), &end, RADIX); if (*end != '\0') throw std::runtime_error("数値じゃない"); return value; } }; struct Empty { }; template<typename T> struct Creater { static T* new_instance(const char* value_str) { return new T(value_str); } }; template<> struct Creater<Empty> { static ValueInt* new_instance(const char* value_str) { return NULL; } }; template <typename T0, typename T1, typename T2 = Empty, typename T3 = Empty, typename T4 = Empty, typename T5 = Empty, typename T6 = Empty, typename T7 = Empty, typename T8 = Empty, typename T9 = Empty> class MultiRadixValueInt : public ValueInt { private: ValueInt* values_[10]; public: MultiRadixValueInt(const char* value_str) : ValueInt(value_str) { init(value_str); } MultiRadixValueInt(const MultiRadixValueInt& other) : ValueInt(other.value_str_.c_str()) { init(other.value_str_.c_str()); } ~MultiRadixValueInt() { clear(); } MultiRadixValueInt& operator=(const MultiRadixValueInt& other) { if (this != &other) { ValueInt::operator=(other); clear(); init(other.value_str_.c_str()); } return *this; } bool is_valid() const { for (int i = 0; i < 10 && values_[i] != NULL; i++) if (values_[i]->is_valid()) return true; return false; } int get_int() const { for (int i = 0; i < 10 && values_[i] != NULL; i++) if (values_[i]->is_valid()) return values_[i]->get_int(); throw std::runtime_error("数値じゃない"); } private: void init(const char* value_str) { values_[0] = Creater<T0>::new_instance(value_str); values_[1] = Creater<T1>::new_instance(value_str); values_[2] = Creater<T2>::new_instance(value_str); values_[3] = Creater<T3>::new_instance(value_str); values_[4] = Creater<T4>::new_instance(value_str); values_[5] = Creater<T5>::new_instance(value_str); values_[6] = Creater<T6>::new_instance(value_str); values_[7] = Creater<T7>::new_instance(value_str); values_[8] = Creater<T8>::new_instance(value_str); values_[9] = Creater<T9>::new_instance(value_str); } void clear() { for (int i = 0; i < 10; i++) delete values_[i]; } }; int main() { char buff[100]; std::cin >> buff; MultiRadixValueInt<RadixValueInt<10>, RadixValueInt<16> > n(buff); if (n.is_valid()) { std::cout << n.get_int()*2 << "\n"; } return 0; }
見て分かる通り、最適化はしてません。
今日の一冊 | |
|
タグ:C++
2009-05-30 09:43
nice!(0)
コメント(0)
トラックバック(0)
コメント 0