2017-01-24 8 views
1

In dem bestimmten Codierungsstandard, der an meinem Arbeitsplatz erzwungen wird, folgen Accessormethoden in einer Klasse einer bestimmten Namenskonvention. Für jede gegebene Elementvariable hat der Getter den gleichen Namen, und dem Setter wird das Präfix Set vorangestellt. Siehe Beispiel unten.Enum & Klassenmitgliedsfunktion mit demselben Namen

class Foo 
{ 
public: 
    int Number() const { return m_number; } 
    void SetNumber(int number) { m_number = number; } 

private: 
    int m_number; 
}; 

Diese schrulligen wird, wenn ich eine Enumeration mit dem gleichen Namen haben:

enum class Number 
{ 
    One, Two, Three 
}; 

class Foo 
{ 
public: 
    Number Number() const { return m_number; } 
    void SetNumber(Number number) { m_number = number; } 

private: 
    Number m_number; 
}; 

Das obige Beispiel wird an einigen Stellen nicht kompiliert, da bestimmen kann der Compiler nicht, wenn ich mit Bezug bin der enum-Name oder der Funktionsname. Also, dies zu beheben, ohne den Codierungsstandard zu verletzen, würde ich :: an Orten der Mehrdeutigkeit verwenden und ich beziehe mich tatsächlich auf die Enum:

enum class Number 
{ 
    One, Two, Three 
}; 

class Foo 
{ 
public: 
    ::Number Number() const { return m_number; } 
    void SetNumber(::Number number) { m_number = number; } 

    void DoStuffWithNumber() 
    { 
     if (m_number == ::Number::One) 
     { 
      // Do stuff 
     } 
    } 

private: 
    Number m_number; 
}; 

Dies ist ein wenig verwirrend für die Leser des Codes, sondern auch ein bisschen nervig, um den Enumerationsnamen in bestimmten Kontexten vollständig zu qualifizieren. Es ist nicht immer geradlinig.

Was ist eine vernünftige Problemumgehung hier? Natürlich könnte ich etwas wie den Accessor zu GetNumber() umbenennen, aber ich bin neugierig zu sehen, welche anderen Lösungen die Leute haben können.

+0

Nun, Sie können den Namen des Getter nicht ändern können Sie? es ist ein Standard für die Codierung am Arbeitsplatz. Also, was ist dann mit dem Namen Plural? –

+1

Wie fühlen Sie sich, Rig des Getters zu bekommen und nur einen Umwandlungsoperator zu liefern ('operator Number() {return m_number;}')? – NathanOliver

+0

@NathanOliver Das ist weniger intuitiv, IMHO. Meine persönliche Präferenz besteht darin, Operatoren zu vermeiden, es sei denn, ich implementiere etwas mit einer eindeutigen und wohldefinierten Semantik (Kopieren/Verschieben, Streams, arithmetische Typen usw.) –

Antwort

2

Sie könnten enum Präfix hinzufügen, um explizit auf enum Klassenname, nicht Funktionsname beziehen.

enum class Number 
{ 
    One, Two, Three 
}; 

class Foo 
{ 
public: 
    enum Number Number() const { return m_number; } 
    void SetNumber(enum Number number) { m_number = number; } 

private: 
    enum Number m_number; // Number here refers to enum class, not function 
}; 

Hinweis: obige Code funktioniert unter g ++, hat aber Probleme in Visual Studio. VS scheint mit Bereichsaufzählungen nicht gut zu funktionieren. Wir können stattdessen auch Uncoped-Enumerationen (ohne das Schlüsselwort class) verwenden.

+1

Sieht so aus, als ob dies nicht in Fällen funktioniert, in denen Sie tatsächlich auf einen der Enumeratoren verweisen müssen. In meinem letzten Codeausschnitt werden Sie sehen, dass ich ":: Number :: One" mache. Du kannst 'enum Number :: One' nicht tun. –

+0

@ void.pointer Es funktioniert in g ++. Welchen Compiler benutzen Sie? –

+0

Haben Sie auch VS 2015 probiert? –

1

Seit Enum können eine Reihe von Werten, nehme ich Plural hier verwenden würde:

enum class Numbers 
//    ^
{ 
    One, Two, Three 
}; 

Das ist nicht unüblich. Z. B. in Google C++ style guide verwenden sie die folgenden Aufzählungen Benennung Beispiel:

enum UrlTableErrors { 
    kOK = 0, 
    kErrorOutOfMemory, 
    kErrorMalformedInput, 
}; 
enum AlternateUrlTableErrors { 
    OK = 0, 
    OUT_OF_MEMORY = 1, 
    MALFORMED_INPUT = 2, 
}; 
0

Warum nicht ein Präfix für Ihre Enum verwenden? Ähnlich wie Sie m_ für Membervariablen verwenden, könnten Sie Ihre Aufzählungen mit einem E-Präfix:

enum class ENumber 
{ 
    One, Two, Three 
}; 

Auf diese Weise hilft es auch schnell Sie erkennen, dass Sie mit einem ENUM zu tun hat hier, und nicht eine Klasse oder Funktion.

1

Ich bevorzuge es, Elementfunktionen mit Kleinbuchstaben und nur statische (Element) Funktionen mit Großbuchstaben zu starten. Falls es eine echte Getter- und Setter-Funktion gibt, würde ich sie auch lieber als Paar wie setNumber und getNumber markieren.

Dies allein würde den Code wie folgt aussehen:

enum class Number 
{ 
    One, Two, Three 
}; 

class Foo 
{ 
public: 
    Number getNumber() const { return m_number; } 
    void setNumber(Number number) { m_number = number; } 
private: 
    Number m_number; 
}; 

Für den Fall eines zugreifenden m_number über eine Funktion nur number genannt würde ich einen Verweis zurückgeben (oder konstante Referenz im const Fall):

enum class Number 
{ 
    One, Two, Three 
}; 

class Foo 
{ 
public: 
    Number& number() { return m_number; } 
    const Number& number() const { return m_number; } 
private: 
    Number m_number; 
}; 

In diesem Fall möchten Sie vielleicht die "benannte Funktion" loswerden und nur Konversationsoperatoren bereitstellen.

Verwandte Themen