In most cases, macros are used when inline functions can be used. In those cases, you should use inline functions (like nearly everyone else said
).
Another problem with macros is that people use them to define constants:
#define MAX_CHARS 256
void main()
{
char array[MAX_CHARS];
// now use the array somehow
}
In those cases, you should use the C++ keyword "const", because it has stricter type-ing and can be used whenever #define-d constants can be used:
const int MAX_CHARS = 256;
void main()
{
char array[MAX_CHARS];
// now use the array somehow
}
However, there are some things that constants and inline functions cannot do. Macros are great for building really complex code out of simple words. This example builds a message map out of a few lines instead of many lines, and eliminates a lot of boring and redundant code (boring at least to the reader).
The example before macros:
LRESULT my_window::on_message(UINT ID, WPARAM wParam, LPARAM lParam)
{
switch( ID )
{
case WM_CLOSE:
return on_close();
case WM_PAINT:
return on_paint();
case WM_DESTROY:
return on_destroy();
default:
return window::on_message(ID, wParam, lParam);
}
}
That code simply calls the proper member function, depending on what message ID was sent to the on_message function. Boring. Let's look at macros. The first thing to do is to break the function down into common parts.
First, we have the beginning of the function, which is always: the name of the function, the opening brace, and the switch statement:
#define BEGIN_MESSAGE_MAP(class_name) LRESULT class_name::on_message(UINT ID, WPARAM wParam, LPARAM lParam) { switch( ID ) {
1 part down, two to go. Now we have the middle part, which is really the only thing that the function writer is concerned about:
#define ON_MESSAGE(ID, function_name) case ID: return function_name();
Finally, we have the end of the function and the default statement:
#define END_MESSAGE_MAP(base_class_name) default: return base_class_name::on_message(ID, wParam, lParam); } }
Now, once we have those macros, we can code the exact same example function like this:
BEGIN_MESSAGE_MAP(my_window)
ON_MESSAGE(WM_CLOSE, on_close)
ON_MESSAGE(WM_PAINT, on_paint)
ON_MESSAGE(WM_DESTROY, on_destroy)
END_MESSAGE_MAP(window)
_Much_ simpler, and the person writing the function can focus on what he needs that function to do, rather than getting caught up in how the switch statement works and when to call the base class version, etc.
-
null_pointerSabre MultimediaEdited by - null_pointer on August 7, 2000 8:26:38 AM