Thursday, February 17, 2011

C++ unions

I was reading Bruce Eckel's Thinking in C++ the other day and I came across a bit of information that I was not aware of: unions can be treated just like classes. That is, they can have constructors and member functions and access control.

I think that this is a neat feature. Combined with the use of templates and operator overloading one can create a shared memory space (just like you normally would with unions) but with a much nicer interface. Consider the following:

#include <stdexcept>
#include <sstream>

template< typename T >
union Bytes {
    private:
        T data_;
        unsigned char bytes_[sizeof(T)];
    public:

        Bytes(const T& t) : data_(t) {}

        T& value () { return data_; }

        size_t size () const { return sizeof(T); }

        void operator= (const T& t) { data_ = t; }

        unsigned char& operator[] (int i) {
            if (i < 0 || i >= size()) {
                std::stringstream ss;
                ss << "Invalid index " << i << " ";
                ss << "(sizeof(T) : " << sizeof(T) << ")";
                throw std::out_of_range (ss.str ());
            }
            return bytes_[i];
        }
};

Now you can have a shared memory space that can be accessed with operator[] for the individual bytes of any POD type (unions do not support objects with constructors) and operator= for setting the value of the type.

The result is mostly syntatic sugar but makes for much more readable code:

Bytes<long> memory(0);  // initial value of 0
memory[1] = 4;          // modify individual bytes. New value 1024
memory = 0;             // reset value to 0

No comments :

Post a Comment