2 Stimmen

Was ist der Unterschied zwischen Defines/Makros/Strukturen und Consts/Funcs/Klassen? (C++)

Ich weiß, dass der Unterschied zwischen Defines und Konstanten darin besteht, dass Konstanten einen Typ haben, und dass zwischen Makros und Funktionen, Funktionen aufgerufen werden und typisiert sind, während Makros untypisiert inline sind. Nicht so sehr der Unterschied zwischen Structs und Klassen, aber ich glaube nicht, dass es einen gibt, abgesehen von der Sache mit den öffentlichen/privaten Standardwerten (und ich beziehe mich hier nur auf C++, nicht auf C).

Wie auch immer, gibt es Zeiten, in denen es effizienter, vorteilhafter oder zumindest sauberer ist, Defines/Makros/Strukturen zu verwenden, als die C++-Versionen, Konstanten, Funktionen und Klassen zu verwenden?

Insbesondere, und weil dies nur eine ohne einen klaren Unterschied (zumindest im endgültigen Programm) zwischen ihnen ist, ist es immer besser, Strukturen als Klassen zu verwenden, und wenn es nicht Effizienz-weise, welche Konventionen für die Verwendung von ihnen verwenden Sie?

5voto

Greg Hewgill Punkte 882617

In einem C++-Programm verwende ich in der Regel eine struct für eine einfache Aggregation von Daten, wie z. B. eine Point Struktur, die eine x und eine y . Ich würde eine class für Objekte, die den Verhalten (Mitgliedsfunktionen), die mit ihnen verbunden sind.

Dies ist natürlich nur eine Konvention, da der Compiler sie mit Ausnahme der beiden oben erwähnten Details (Standardvererbung und Standardsichtbarkeit der Mitglieder) fast identisch behandelt.

2voto

the_mandrill Punkte 28354

Makros werden in der Regel verachtet (wahrscheinlich zu Recht), weil sie keinerlei Typsicherheit bieten. Sie sind jedoch nützlich für Dinge, die man in C/C++ nicht direkt tun kann, insbesondere der Stringize-Operator (#) zur Umwandlung von Typen, Variablennamen und Enums in Strings, die in den Code eingebettet werden:

#define STRINGIZE(ARG) #ARG

Makros können auch für Boilerplate-Code nützlich sein, wenn Sie eine Menge sich wiederholenden Code haben, z. B. um jedes Mitglied einer Aufzählung in eine Tabelle einzufügen. Die Verwendung eines Makros kann viel sauberer sein als eine Funktion. MFC verwendet Makros auf diese Weise, um z. B. Message-Handler zu definieren.

0voto

stonemetal Punkte 6058

Der wichtigere Unterschied zwischen den Definitionen \macros und Konstanten \functions ist der Geltungsbereich.

Konstanten sollten immer ein Gewinn sein, da der Compiler sie so optimiert, dass sie genauso gut funktionieren wie Defines, ohne dass ihre Übersichtlichkeit darunter leidet.

Der Fall für Funktionen ist ähnlich alles, was Sie tun können, mit einem Makro können Sie mehr sicher mit einer Funktion zu tun, und ich habe noch über einen Compiler, der nicht bieten irgendeine Möglichkeit, Inlining zu erzwingen, um Verhalten identisch mit dem Makro Fall zu machen laufen.

0voto

Jörg Haubrichs Punkte 2185

Ich würde Funktionen und Konstanten gegenüber Defines und Makros bevorzugen, weil sie semantisch eindeutiger sind, so dass man ein sinnvolleres und kontrollierbares Feedback von IDEs und Compilern erhält.

0voto

StackedCrooked Punkte 33522

Konkret, und weil ohne einen klaren Unterschied (zumindest zumindest im endgültigen Programm) zwischen ist es jemals besser, Strukturen zu verwenden als Klassen zu verwenden, und wenn nicht, dann aus Effizienzgründen nicht, welche Konventionen für Sie sie verwenden?

Strukturen sind besser für die Definition von Speicherblöcken geeignet. Zum Beispiel hat die Windows-API einen Aufruf namens CreateDialogIndirect, einer seiner Parameter ist ein Speicherblock, der wie folgt beschrieben wird:

[in] Zeiger auf ein globales Speicherobjekt c CreateDialogIndirect verwendet, um das das Dialogfeld zu erstellen. Eine Dialogfeldvorlage besteht aus einer Kopfzeile, die das das Dialogfeld beschreibt, gefolgt von einem oder mehreren zusätzlichen Datenblöcken, die jedes der Steuerelemente in der Dialogbox beschreiben Dialogfeldes beschreiben. Die Vorlage kann entweder das Standardformat oder das erweiterte Format verwenden. In einem Standard Vorlage ist die Kopfzeile eine DLGTEMPLATE Struktur, gefolgt von zusätzlichen Arrays mit variabler Länge. Die Daten für jedes Steuerelements bestehen aus einer DLGITEMTEMPLATE-Struktur, gefolgt von zusätzlichen Arrays mit variabler Länge.

Das klingt alles sehr komplex. Sicherlich würden Sie versuchen, einen Heap-Allokationspuffer von Speicher zuzuweisen und versuchen, ihn gemäß der Beschreibung zu füllen. Sie können jedoch Structs verwenden, um die Arbeit zu vereinfachen:

 struct {
    DLGTEMPLATE t;
    short noMenu;
    short defaultClass;
    short title;
  } templ;

  templ.t.style = style;
  templ.t.dwExtendedStyle = extendedStyle;
  templ.t.cdit = 0;
  // etc...
  HWND hDlg = ::CreateDialogIndirectParam(hInstance,
                                          &templ.t,
                                          hWndParent,
                                          (DLGPROC)DialogProc,
                                          NULL);

Ich denke, dies ist eine Situation, in der Strukturen eindeutig eine bessere Wahl als Klassen sind. Es würde mit einer Klasse funktionieren, aber das würde sehr seltsam aussehen, meinst du nicht?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X