Parameterlos #define
s vs. const
s:
Solange das Makro tatsächlich durch eine Konstante oder eine Variable ersetzt wird, die sich nicht ändert, erreichen beide dasselbe. Es gibt jedoch einige subtile Unterschiede, wenn die erste Aussage nicht zutrifft. Nehmen wir die folgende Klasse als Beispiel:
class my_class {
explicit my_class(int i);
explicit my_class(const my_class& copy_from);
};
// implementation defined elsewhere, it's irrelevant
Wenn Sie das Folgende tun:
#define MY_CONST_OBJECT my_class(1)
my_class obj1(MY_CONST_OBJECT);
my_class obj2(MY_CONST_OBJECT);
dann wird der Konstruktor von my_class
dessen Parameter ein int
wird zweimal aufgerufen. Und der folgende Code ist illegal:
my_class& ref1 = MY_CONST_OBJECT;
my_class& ref2 = MY_CONST_OBJECT;
Wenn Sie jedoch Folgendes tun:
const my_class my_const_object(1);
my_class obj1(my_const_object);
my_class obj2(my_const_object);
dann wird der Konstruktor von my_class
dessen Parameter ein int
wird nur einmal aufgerufen. Und der ursprünglich illegale Code ist nun legal:
my_class& ref1 = my_const_object;
my_class& ref2 = my_const_object;
Parametrisch #define
s vs. inline
Funktionen:
Solange die Makroparameter keine Ausdrücke sind, erreichen beide dasselbe. Es gibt jedoch einige subtile Unterschiede, wenn die erste Aussage nicht zutrifft. Nehmen wir dieses Makro als Beispiel:
#define MAX(A,B) = ((A) < (B)) ? (A) : (B)
Dieses Makro konnte nicht die rand()
(oder jede andere Funktion, deren Verhalten entweder den Zustand des gesamten Programms beeinflusst und/oder von ihm abhängt) als Parameter, da rand()
würde zweimal aufgerufen werden. Stattdessen ist es sicher, die folgende Funktion zu verwenden:
template < class _Type >
_Type max( _Type a, _Type b ) { return (a < b) ? a : b ; }
struct
s vs. class
es
Es gibt keinen wirklichen Unterschied zwischen struct
s und class
als der Standard-Zugriffsspezifizierer für Basisklassen und Mitglieder ist public
und die des letzteren ist private
. Es ist jedoch unzivilisiert, zu erklären, dass struct
s, die Methoden und damit ein Verhalten haben, und es ist auch unzivilisiert, zu erklären class
die nur über Rohdaten verfügen, auf die direkt zugegriffen werden kann.
Die Erklärung einer class
die zur Verwendung als struct
etwa so:
class my_class {
public:
// only data members
};
ist geschmacklos. struct
s mit Konstruktoren haben vielleicht einen gewissen Nutzen, z.B. um die Initialisierung mit Mülldaten zu verhindern, aber ich würde auch von ihnen abraten.