When I first encountered fixed point numbers I found this article very helpful, and it does suggest one way of representing fixed point values.
http://www.embedded.com/columns/15201575?_requestid=65598
I didn't wind up using his union representation for fixed point numbers though. I mostly have experience with fixed point in C, so I haven't had the option to use a class either. For the most part though, I think that defining your number of fraction bits in a macro and using descriptive variable names makes this fairly easy to work with. Also, I've found that it is best to have macros or functions for multiplication and especially division, or you quickly get unreadable code.
For example, with 24.8 values:
#include "stdio.h"
/* Declarations for fixed point stuff */
typedef int int_fixed;
#define FRACT_BITS 8
#define FIXED_POINT_ONE (1 << FRACT_BITS)
#define MAKE_INT_FIXED(x) ((x) << FRACT_BITS)
#define MAKE_FLOAT_FIXED(x) ((int_fixed)((x) * FIXED_POINT_ONE))
#define MAKE_FIXED_INT(x) ((x) >> FRACT_BITS)
#define MAKE_FIXED_FLOAT(x) (((float)(x)) / FIXED_POINT_ONE)
#define FIXED_MULT(x, y) ((x)*(y) >> FRACT_BITS)
#define FIXED_DIV(x, y) (((x)<<FRACT_BITS) / (y))
/* tests */
int main()
{
int_fixed fixed_x = MAKE_FLOAT_FIXED( 4.5f );
int_fixed fixed_y = MAKE_INT_FIXED( 2 );
int_fixed fixed_result = FIXED_MULT( fixed_x, fixed_y );
printf( "%.1f\n", MAKE_FIXED_FLOAT( fixed_result ) );
fixed_result = FIXED_DIV( fixed_result, fixed_y );
printf( "%.1f\n", MAKE_FIXED_FLOAT( fixed_result ) );
return 0;
}
Which writes out
9.0
4.5
Note that there are all kinds of integer overflow issues with those macros, I just wanted to keep the macros simple. This is just a quick and dirty example of how I've done this in C. In C++ you could make something a lot cleaner using operator overloading. Actually, you could easily make that C code a lot prettier too...
I guess this is a long-winded way of saying: I think it's OK to use a typedef and macro approach. So long as you're clear about what variables contain fixed point values it isn't too hard to maintain, but it probably won't be as pretty as a C++ class.
If I was in your position, I would try to get some profiling numbers to show where the bottlenecks are. If there are relatively few of them then go with a typedef and macros. If you decide that you need a global replacement of all floats with fixed-point math though, then you'll probably be better off with a class.