Class of int that goes from 0 to 6

Is it possible to create a class that contains an int that can only take values of [0,1,2,3,4,5,6]? I mean, like a class that automatically changes the value of that int if it gets out of that range?
I'm new with classes so my idea would be to write something like this:

1
2
3
4
5
6
7
class zerotosix_t{
  public:
    unsigned int x;

    if(x > 6)
        x %= 7;
};


But this obviously isn't the right way.
How can I do this?

Thanks in advance :)
Last edited on
yea just do it in the constructor.
You may want to add some C++ operators to your class ensuring values staying in range. F.e. assignment operators (operator=, operator+=, ...), increment and decrement operators (operator++, ...), ...

F.e.:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Int07
{
private:
    static const unsigned int MIN_INT07 = 0;
    static const unsigned int MAX_INT07 = 7;

private:
    unsigned int value;

private:
    void assign(unsigned int newValue);

public:
    Int07(unsigned int initValue = 0) :
        value(0)
    {
        assign(initValue);
    }

    Int07 &operator=(const unsigned int newValue);

    operator unsigned int()
    {
        return (unsigned int) value;
    }

} /* Int07 */;
     
void Int07::assign(unsigned int newValue)
{
    if (newValue > MAX_INT07)
    {
        throw range_error("Int07::assign(): new value out of range");
    }
    value = newValue;

} /* Int07::assign() */

Int07 &Int07::operator=(const unsigned int newValue)
{
    assign(newValue);

    return *this;

} /* Int07::operator=() */
That's what I was asking for, thank you.
But these lines of code confuse me a bit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//...
public:
    Int07(unsigned int initValue = 0) :
        value(0)
    {
        assign(initValue);
    }

    Int07 &operator=(const unsigned int newValue);

    operator unsigned int()
    {
        return (unsigned int) value;
    }

}

//... 


Would you mind explaining a bit what each line does, please?
Last edited on
Line 2..7: The constructor initializes value using initValue.

Line 9: The assignment operator assigns a new value returning a reference to ourself (see cplusplus-tutorial).

Line 11..14: This cast operator returns value as unsigned int. Otherwise you couldn't say f.e.:

1
2
3
4
5
6
7
8
9
10
11
void foo()
{
    Int07 a(6); // Create a new Int07 using initial value 6

    cout << "a = " << a << endl;

    unsigned int b;

    b = 77 * a;

} /* foo() */


Try the above example after removing lines 11..14.
Last edited on
You may want an enum instead.
@tcs: your code does not fully satisfies OP needs:
like a class that automatically changes the value of that int if it gets out of that range?
//...
1
2
    if(x > 6)
        x %= 7;
Wrap number around instead of throwing exception

Here is an (imperfect) example of templated class which does that. You still need to implement rest of the assigment family operators and increment/decrement. ALso for fun you can try to make it work with all ranges (currently not all ranges supported) and support different types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>

template<typename T>
inline T proper_mod(T x, T y)
{ return ((x % y) + y) % y; }

template<int L, int H>
class bounded_int
{
public:
    bounded_int(int f) : value(f)
    { fix(); }

    bounded_int(): bounded_int(0) {};

    bounded_int& operator=(int from)
    {
        value = from;
        fix();
        return *this;
    }

    operator int() const
    { return value; }

private:
    int value;

    void fix()
    {
        constexpr int range = H - L + 1;
        value = proper_mod(value - L, range) + L;
    }
};


int main()
{
    bounded_int<1, 6> x;
    bounded_int<-5, 5> y = 11;
    y = y + 10;
    std::cout << x << ' ' << y << '\n';
    y = y + 7;
    x = y;
    std::cout << x << ' ' << y << '\n';
}
6 -1
1 -5

Last edited on
Whew, templates and clases are really confusing me.
I gotta spend some more time analizing these codes.

I got the idea tho. Thanks guys!
@MiiNiPaa: Slight mistake:
Line 14, initialize it with L.
this allows for ranges not including 0 to be correctly default-constructed.
In your example, the first X will print 0, but it must be in range 1-6.
It will actually print 6 as it calls parametrized constructor which performs wraparound.
http://coliru.stacked-crooked.com/a/db959259d8172008

Initialization with L is a good idea too, I thought about it (and about ditching default constructor completely or disabling it for ranges not including 0) but decided to be consistent with int initialization.
Sorry, just gave it a fast look and didnt notice you called the other constructor instead of initializing "value" directly.
Topic archived. No new replies allowed.