SSブログ

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;
}

見て分かる通り、最適化はしてません。

[飛行機] 今日の一冊
詐欺師入門―騙しの天才たち その華麗なる手口

詐欺師入門―騙しの天才たち その華麗なる手口

  • 作者: デヴィッド・W. モラー
  • 出版社/メーカー: 光文社
  • 発売日: 1999/09
  • メディア: 単行本

タグ:C++
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。