2010-01-29 21 views
5

Ist dieser Code mehrdeutig oder ist er völlig in Ordnung (durch Standards genehmigt/hat ein konsistentes Verhalten für alle existierenden Compiler)?Ist das mehrdeutig oder ist es völlig in Ordnung?

struct SCustomData { 
    int nCode; 
    int nSum; 
    int nIndex; 
    SCustomData(int nCode, int nSum, int nIndex) 
     : nCode(nCode) 
     , nSum(nSum) 
     , nIndex(nIndex) 
    {} 
}; 

edit:
ja, ich beziehe mich auf die Tatsache, dass die Mitgliedsvariablen mit formalen Parametern des Konstruktor den gleichen Namen haben.

+3

Ich werde ehrlich sein, ich musste es zweimal lesen ... Ich wäre wahrscheinlich ein unglücklicher Entwickler, wenn ich zweimal den gleichen Code lesen müsste. –

+3

Entschuldigung, aber was soll daran mehrdeutig sein? Sieht einfach für mich aus. –

+0

Was mehrdeutig (für den Menschen) ist, ist die gleiche Kennung für ein Attribut und einen Parameter zu haben ... –

Antwort

6

Nein, in diesem Fall gibt es keine Zweideutigkeit, aber bedenken Sie folgendes:

struct SCustomData { 
//... 
    void SetCode(int nCode) 
    { 
      //OOPS!!! Here we do nothing! 
      //nCode = nCode; 

      //This works but still error prone 
      this->nCode = nCode; 
    } 
}; 

Sie sollten ihr Augenmerk auf eine der vorhandenen Codierung Stile zeichnen. Zum Beispiel General Naming Rule in Google C++ Coding Styles oder lesen Sie ausgezeichnete Buch "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" von Herb Sutter und Andrei Alexandrescu.

+0

Einfache Regel, die ich immer benutze: erster Buchstabe Großbuchstaben für Parameter, Kleinbuchstaben für private Felder. –

+0

Ich bevorzuge Sutters Stil: Camel Case - für Parameter (Code - in diesem Beispiel), Camel Case und Unterstrich (_) - für private Felder (Code_ - in diesem Beispiel). –

4

Ihr Beispiel ist unzweideutig (für mich), aber es ist keine gute Übung, weil es schnell so zweideutig wie die Hölle werden kann.

Es ist lange her, seit ich C++ in Wut geschrieben habe, also rate ich, was das Folgende tun wird.
Haben Sie KNOW was wird es tun? Bist du sicher?

class Noddy 
{ 
    int* i; 
    Noddy(int *i) 
    : i(i) 
    { 
     if(i == NULL) 
      i = new int; 
    } 
}; 
+1

Ja, ich weiß, was es tun wird, aber ich würde kein Geld setzen, dass meine Kollegen tun :) –

+0

Sag mir Sag es mir Sag mir! Bezieht sich das innere 'i' auf das 'am nächsten erklärte': das Argument? (Die Initialisiererliste kann sich offensichtlich nur auf das Mitglied beziehen) – xtofl

+2

@xtofl: Korrigieren, tun, was es "aussieht", wie es tun sollte, es müsste "this -> i" in den geschweiften Klammern sein {} –

1

Wenn Sie den gleichen Namen für Mitglieder und Konstruktorargumente verwenden, ist das absolut in Ordnung. Allerdings könnten Sie einige Leute finden, die darauf bestehen, dass es aus irgendeinem Grund schlecht ist.

Wenn Sie auf die Mitglieder im Konstruktorhauptteil zugreifen müssen, müssen Sie vorsichtig sein - geben Sie den Argumenten unterschiedliche Namen, oder verwenden Sie this->, um auf Mitglieder zuzugreifen.

Wenn Sie pseudohungarische Warzen verwenden, um Leute daran zu erinnern, dass ganze Zahlen ganze Zahlen sind, dann ist das technisch erlaubt, hat aber absolut keine Vorteile und macht den Code viel schwerer zu lesen. Bitte tu es nicht.

+1

Als einer von "diesen Leuten", sind meine Gründe a) die OP musste danach fragen - also wahrscheinlich werden andere lesen solche Code und b) sehen Ihre zweite Para. –

+1

@Neil: (a) es ist nicht möglich, C++ so zu schreiben, dass Leute, die es lesen, C++ nicht kennen müssen, (b) ich stimme völlig zu, in einer Funktion mit einem nicht leeren Body Membervariablen zu verstecken mit Parametern wird nach Ärger gefragt. Der Unterschied ist, dass es in (b) leicht ist, die beiden versehentlich zu verwechseln, auch wenn Sie die Sprache gut kennen, nur weil Sie das Verstecken von einer Minute zur nächsten vergessen haben. Dies führt zu Fehlern. In (a) gibt es nur eine plausible Absicht des Codes und die Frage ist, ob Sie sich bewusst sind, dass es legal ist. Dies führt zu einem Lernmoment. –

1

Im Allgemeinen habe ich Instanzvariablen mit Unterstrichen und benannten Parametern im Konstruktor ohne Präfix vorangestellt. Zumindest wird dies Ihre Parameter von Ihren Instanzvariablen disambiguieren. Es macht auch das Leben weniger hektisch, wenn es im Körper des Konstruktors initialisiert wird.

Ich mag es nicht, die Variablen so zu stapeln, wie es in der Frage geschrieben wurde. Ich mag es, vertikalen Platz zu sparen, und es ist auch einfacher für mich, von links nach rechts zu lesen. (Dies ist eine persönliche Vorliebe von mir, keine zwingende Regel oder etwas Ähnliches.)

+4

Leider sind Bezeichner, die mit dem Unterstrich beginnen, sowohl in C als auch in C++ reserviert. – aib

0

Es ist vollkommen Standardkonform, aber dort sind Compiler draußen, die Mitgliedsvariablen nicht akzeptieren würden, die den gleichen Namen wie Konstruktorparameter haben . Tatsächlich musste ich meine Open-Source-Bibliothek aus diesem Grund ändern. Siehe this patch

1

Ich würde sagen, dass das völlig in Ordnung ist.

Es ist mein bevorzugter Stil für Konstruktoren, die die Initialisierungsliste verwenden und keinen Code haben. Ich denke, dass es Verwirrung reduziert, weil es offensichtlich ist, welcher Konstruktorparameter zu welchem ​​Mitglied geht.

Verwandte Themen