Determine endianness
The easiest is to determine if the targetted architecture is big- or little-endian at compile time. On linux this is straightforward: just include /usr/include/endian.h. You can then use the defined variables __BYTE_ORDER, __LITTLE_ENDIAN and __BIG_ENDIAN. For example:
Convert a rgba image to grayscale
// read 4 bytes at once
unsigned int * p = reinterpret_cast(some_image);
unsigned int * end = p + width*height;
// the resulting gray scale image
unsigned char out_image[width*height]
unsigned char * p_out = out_image;
for(; p != end; ++p)
{
unsigned int fourBytes = *p;
#if __BYTE_ORDER == __LITTLE_ENDIAN
b = fourBytes >> 16;
g = fourBytes >> 8;
r = fourBytes;
#elif __BYTE_ORDER == __BIG_ENDIAN
r = fourBytes >> 24;
g = fourBytes >> 16;
b = fourBytes >> 8;
#endif
*p_out = (r >> 2) + (g >> 1) + (b >> 2);
p_out++;
}
Singleton pattern
Imagine that your system depends on a set of parameters that, e.g. are read from a configuration file at start, or entered via a GUI, etc. You can put all your configuration parameters in an object. A nice pattern to use in that case is the singleton, which guarantees that there is only single config object at any time during the life of the program.
class Config
{
public:
static Config & GetConfig()
{
static Config c;
return c;
}
// some more methods here
// ...
private:
// make the cstor, copy and assignement operator private
Config() {}
Config( const Config & );
void operator=( const Config & );
};
// then anywhere in your code you can write
Config & MyConfig = Config::GetConfig();
// and MyConfig will always refer to the same object.
MyConfig.SetParameter(...)
