Parameterless #define
s vs. const
s:
As long as the macro is actually replaced by a constant or a variable that doesn't change, both achieve the same thing. But there are some subtle differences if the former statement doesn't hold. Let's use the following class as an example:
class my_class {
explicit my_class(int i);
explicit my_class(const my_class& copy_from);
};
// implementation defined elsewhere, it's irrelevant
If you do the following:
#define MY_CONST_OBJECT my_class(1)
my_class obj1(MY_CONST_OBJECT);
my_class obj2(MY_CONST_OBJECT);
then the constructor of my_class
whose parameter is an int
is called twice. And the following code is illegal:
my_class& ref1 = MY_CONST_OBJECT;
my_class& ref2 = MY_CONST_OBJECT;
However, if you do the following:
const my_class my_const_object(1);
my_class obj1(my_const_object);
my_class obj2(my_const_object);
then the the constructor of my_class
whose parameter is an int
is called only once. And the originally illegal code is now legal:
my_class& ref1 = my_const_object;
my_class& ref2 = my_const_object;
Parametric #define
s vs. inline
functions:
As long as the macro parameters are not expressions, both achieve the same thing. But there are some subtle differences if the former statement doesn't hold. Let's take this macro as an example:
#define MAX(A,B) = ((A) < (B)) ? (A) : (B)
This macro could not take rand()
(or any function whose behavior either affects the state of the whole program and/or depends on it) as a parameter, because rand()
would be called twice. Instead, using the following function is safe:
template < class _Type >
_Type max( _Type a, _Type b ) { return (a < b) ? a : b ; }
struct
s vs. class
es
There is no real difference between struct
s and class
es other than the former's default access specifier for base classes and members is public
and the latter's is private
. However, it's uncivilized to declare struct
s that have methods and, thus, behavior, and it's also uncivilized to declare class
es that only have raw data that can be accessed directly.
Declaring a class
that is meant to be used as a struct
, like this:
class my_class {
public:
// only data members
};
is in bad taste. struct
s with constructors might have some uses, such as not allowing initialization with trash data, but I would recommend against them as well.