Domanda

Vengo da un mondo .NET e sono nuovo a scrivere C ++. Mi sto solo chiedendo quali sono le convenzioni di denominazione preferite quando si tratta di nominare variabili locali e membri struct.

Ad esempio, il codice legacy che ho ereditato ha molte di queste:

struct MyStruct
{
   TCHAR           szMyChar[STRING_SIZE];
   bool            bMyBool;
   unsigned long   ulMyLong;
   void*           pMyPointer;
   MyObject**      ppMyObjects;
}

Provenendo da uno sfondo C # sono rimasto scioccato nel vedere le variabili con notazione ungherese (non potevo smettere di ridere del prefisso in pp la prima volta che l'ho visto).

Preferirei piuttosto nominare le mie variabili in questo modo (anche se non sono sicuro che la maiuscola della prima lettera sia una buona convenzione. Ho visto altri modi (vedi link sotto)):

struct MyStruct
{
   TCHAR           MyChar[STRING_SIZE];
   bool            MyBool;
   unsigned long   MyLong;
   void*           MyPointer;
   MyObject**      MyObjects;
}

La mia domanda: questo (il primo modo) è ancora un modo preferito per nominare le variabili in C ++?

References:

http://geosoft.no/development/cppstyle.html

http://www.syntext.com/books/syntext-cpp- conventions.htm

http://ootips.org/hungarian-notation.html

Grazie!

È stato utile?

Soluzione

Questo tipo di notazione ungherese è abbastanza inutile, e forse peggio che inutile se devi cambiare il tipo di qualcosa. ( Il tipo corretto di notazione ungherese è una storia diversa. )

Ti suggerisco di usare qualunque cosa faccia il tuo gruppo. Se sei l'unica persona che lavora al programma, chiamali come preferisci.

Altri suggerimenti

La cosa più importante è essere coerenti. Se lavori con una base di codice legacy, dai un nome alle variabili e alle funzioni coerentemente con la convenzione di denominazione del codice legacy. Se stai scrivendo un nuovo codice che si interfaccia solo con il vecchio codice, usa la convenzione di denominazione nel nuovo codice, ma sii coerente anche con te stesso.

No. La "notazione ungherese sbagliata" - in particolare la pp per la doppia indiretta - aveva un senso per i primi compilatori in C dove potevi scrivere

int * i = 17;
int j = ***i;

senza nemmeno un avvertimento da parte del compilatore (e potrebbe anche essere un codice valido sull'hardware giusto ...).

La "vera notazione ungherese" (come collegato dal capo Geek) l'IMO è ancora un'opzione valida, ma non necessariamente preferita. Una moderna applicazione C ++ di solito ha dozzine o centinaia di tipi, per i quali non troverai prefissi adatti.

Lo uso ancora localmente in alcuni casi in cui devo mescolare ad es. variabili intere e float che hanno nomi molto simili o addirittura identici nel dominio problematico, ad es.

float fXmin, fXmax, fXpeak; // x values of range and where y=max
int   iXmin, iXMax, iXpeak; // respective indices in x axis vector

Tuttavia, quando si mantiene il codice legacy che segue alcune convenzioni in modo coerente (anche se in modo approssimativo), è necessario attenersi alle convenzioni utilizzate lì - almeno nei moduli / unità di compilazione esistenti da mantenere.

Il mio ragionamento: lo scopo degli standard di codifica è rispettare il principio della minima sorpresa. L'uso costante di uno stile è più importante di quello che usi.

Che cosa non piace o deride su " ppMyObjects " in questo esempio a parte essere un po 'brutto? Non ho opinioni forti in entrambi i casi, ma comunica immediatamente informazioni utili che "MyObjects" no.

Sono d'accordo con le altre risposte qui. O continua a utilizzare lo stile che ti viene dato dal tramandato per coerenza, o escogita una nuova convenzione che funzioni per il tuo team. È importante che il team sia d'accordo, poiché è quasi garantito che cambierai gli stessi file. Detto questo, alcune cose che ho trovato molto intuitive in passato:

Le variabili dei membri class / struct dovrebbero distinguersi - di solito le antepongo tutte con m_
Le variabili globali dovrebbero risaltare - usa il prefisso con g_
Le variabili in generale dovrebbero iniziare con le lettere minuscole
I nomi delle funzioni in generale dovrebbero iniziare con le maiuscole
Le macro e, eventualmente, gli enumeratori dovrebbero essere tutte in maiuscolo
Tutti i nomi dovrebbero descrivere cosa fa la funzione / variabile e non dovrebbero mai descriverne il tipo o il valore.

Sono anch'io una persona notazione ungherese, perché trovo che offra leggibilità al codice e preferisco di gran lunga il codice autocompattante a commenti e ricerche.

Detto questo, penso che tu possa fare un caso per sacrificare il tuo stile preferito e una manutenibilità aggiuntiva per l'unità della squadra. Non compro l'argomento della coerenza per motivi di leggibilità uniforme del codice, soprattutto se la tua leggibilità di riduzione per coerenza ... non ha senso. Andare d'accordo con le persone con cui lavori, tuttavia, potrebbe valere un po 'più di confusione sui tipi che guardano le variabili.

La notazione ungherese era comune tra gli utenti delle API Win32 e MFC. Se i tuoi predecessori lo stavano usando, probabilmente puoi continuare a usarlo (anche se fa schifo). Il resto del mondo C ++ non ha mai avuto questa convenzione mortale, quindi non usarla se stai usando qualcosa di diverso da quelle API.

Penso che troverai ancora che la maggior parte dei negozi che programmano in Visual C ++ si attacca con notazione ungherese o almeno una versione annacquata di esso. Nel nostro negozio, metà della nostra app è legacy C ++ con un nuovo brillante livello C # in alto (con un livello C ++ gestito nel mezzo.) Il nostro codice C ++ continua a usare la notazione ungherese ma il nostro codice C # usa la notazione come hai presentato. Penso che sia brutto, ma è coerente.

Dico, usa quello che il tuo team vuole per il tuo progetto. Ma se stai lavorando su un codice legacy o ti unisci a un team, mantieni lo stile presente per coerenza.

Dipende tutto dalle preferenze personali. Ho lavorato per 2 aziende entrambe con schemi simili, in cui i membri membri sono chiamati m_varName. Non ho mai visto la notazione ungherese in uso sul lavoro, e davvero non mi piace, ma di nuovo in preferenza. La mia sensazione generale è che gli IDE dovrebbero occuparsi di dirti di che tipo è, quindi finché il nome è abbastanza descrittivo di quello che fa (m_color, m_shouldBeRenamed), allora va bene. L'altra cosa che mi piace è la differenza tra variabile membro, var locale e denominazione costante, quindi è facile vedere cosa sta succedendo in una funzione e da dove provengono i var. Membro: m_varName Cost: c_varName local: varName

Preferisco anche CamelCase, anzi per lo più ho visto persone che usano CamelCase in C ++. Personalmente non utilizzo alcun prefisso previsto per i membri e le interfacce privati ??/ protetti:

class MyClass : public IMyInterface {
public:
    unsigned int PublicMember;
    MyClass() : PublicMember(1), _PrivateMember(0), _ProtectedMember(2) {}
    unsigned int PrivateMember() {
        return _PrivateMember * 1234; // some senseless calculation here
    }
protected:
    unsigned int _ProtectedMember;
private:
    unsigned int _PrivateMember;
};
// ...
MyClass My;
My.PublicMember = 12345678;

Perché ho deciso di omettere i prefissi per i membri pubblici: Perché ai membri pubblici è possibile accedere direttamente come nelle strutture e non scontrarsi con nomi privati. Invece usando i trattini bassi ho visto anche persone che usano la prima lettera minuscola per i membri.

struct IMyInterface {
    virtual void MyVirtualMethod() = 0;
};

Le interfacce contengono per definizione solo metodi virtuali puri che devono essere implementati in un secondo momento. Comunque nella maggior parte delle situazioni preferisco lezioni astratte, ma questa è un'altra storia.

struct IMyInterfaceAsAbstract abstract {
    virtual void MyVirtualMethod() = 0;
    virtual void MyImplementedMethod() {}
    unsigned int EvenAnPublicMember;
};

Vedi Manuale standard di codifica C ++ ad alta integrità per qualche altra ispirazione.

Il nostro team utilizza Convenzione sul codice C ++ di Google :

Questo è un esempio di nome variabile:

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.

Se usi CamelCase, la convenzione è di capitalizzare la prima lettera per classi di classi e nomi di tipi non primitivi e in minuscolo la prima lettera per i membri dei dati. La capitalizzazione dei metodi tende ad essere un miscuglio, i miei metodi tendono ad essere verbi e sono già distinti dai genitori quindi non capitalizzo i metodi.

Personalmente non mi piace leggere il codice CamelCase e preferisco i caratteri di sottolineatura in minuscolo identificatori di dati e metodi, capitalizzazione dei tipi e prenotazione di maiuscole per gli acronimi e il raro caso in cui uso una macro (avvertendo che si tratta di un MACRO).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top