Another side of this is validation and conversion, for example, let's say we have a graphics library that supports setting pixels to R, G, B colours, and we want to support 24 bpp and 16 bpp (5,6,5)
We'd first make a base class for pixel colour, which is just there to define the interface. We derive from this class to make all the REAL implementations [this is just a trivial sample - a real example of how to do this would require quite a bit more code, and could probably be done partially using templates]
Code:
class BaseColor
{
public:
BaseColor();
virtual ~BaseColor();
virtual SetColor(int r, int g, int b) = 0;
virtual GetColor(int &r, int &g, int &b) = 0;
};
class Color24BPP: public BaseColor
{
private:
BYTE m_r;
BYTE m_g;
BYTE m_b;
public:
Color24BPP();
~Color24BPP();
virtual SetColor(int r, int g, int b)
{
// Clamp colours in 0..255 range. We assume the number is positive.
m_r = min(255, r);
m_g = min(255, g);
m_b = min(255, b);
}
virtual GetColor(int &r, int &g, int &b)
{
r = m_r;
g = m_g;
b = m_b;
}
};
class Color16BPP: public BaseColor
{
private:
BYTE m_r;
BYTE m_g;
BYTE m_b;
public:
Color16BPP();
~Color16BPP();
virtual SetColor(int r, int g, int b)
{
// Clamp colours to 5, 6, 5 bits. We assume the number is positive.
m_r = min(31, r >> 3);
m_g = min(63, g >> 2);
m_b = min(31, b >> 3);
}
virtual GetColor(int &r, int &g, int &b)
{
// Make it back into 8 bit numbers. Or in the upper bits in the bottom to make
// some data in the bottom bits.
r = m_r << 3 | m_r >> 3;
g = m_g << 2 | m_g >> 4;
b = m_b << 3 | m_b >> 3;
}
};
--
Mats