Convenzione di codifica: file di intestazione / interfaccia C ++

6

Sto leggendo un PDF su programmazione C ++ da questa pagina sul sito di Stanford. Dice che quando crei un file di intestazione C ++ per un'interfaccia di libreria, usa un comando di preprocessore #ifndef per assicurarti di non compilare la stessa interfaccia due volte.

Quindi, la tua intestazione sarebbe simile a questa:

/**
  MyFile.h
*/

#ifndef _MyFile_h
#define _MyFile_h

// Function prototypes

#endif

Ma ho sempre sentito dire che usare comandi di preprocessore come #define è (o porta rapidamente a) una cattiva pratica di codifica. Sto solo iniziando ad imparare C ++, quindi non voglio ottenere qualcosa di radicato che sia male.

Domanda: è lo stile di codifica "corretto" per utilizzare i comandi del preprocessore come sopra?

    
posta apnorton 12.06.2013 - 17:30
fonte

3 risposte

13

Questo è uno dei pochi usi delle macro C ++ ampiamente accettato. Solitamente viene chiamato include guard . In alternativa, i compilatori più moderni supportano #pragma once . Questo è molto più pulito, ma leggermente meno portatile.

    
risposta data 12.06.2013 - 17:38
fonte
6

Ci sono alcune funzionalità linguistiche che vengono abusate da alcuni programmatori che non hanno imparato meglio. Nel corso del tempo, la tendenza dell'abuso porta a un largo consenso di "pratica / caratteristica X è cattiva" e si propaga in una reazione quasi istintiva di "OMG vedo pratica / caratteristica X in questo codice, questo codice deve essere bruciato"

Le variabili globali o singleton sono un altro grande esempio di questo. È ASSOLUTAMENTE necessario averli e usarli QUANDO è appropriato. Il problema è che il 98% del codice che vedi là fuori, queste pratiche non dovrebbero essere usate.

Come qualcuno che è nuovo della lingua, devi imparare cosa fa ciascuna funzione, ma non scartarla e dimenticarla solo perché hai sentito da qualche parte che è brutto. Scopri perché è sbagliato e impara a codificare in modo migliore in modo da non averne bisogno. Ma dopo aver superato tutto questo, ci saranno momenti in cui il preprocessore è la risposta giusta per certi tipi di problemi.

Il più grande problema con il preprocessore (oltre a non essere dattiloscritto e tutto il resto ...) è che la gente inserisce il codice. Quindi, forse un po 'più di codice, quindi forse un'istruzione if. Quando esegui il debug del codice con il preprocessore, tutto ciò che vedi è il punto di esecuzione sulla tua macro senza alcuna idea utile di ciò che accade dietro di esso.

Come caso estremo, una volta ho lavorato con un ragazzo con oltre 200 macro di linea. Quando aveva bisogno di eseguirne il debug, li copiava e incollava direttamente nel codice in cui era stata usata la macro e rimuoveva tutti i \ 'dalla fine della riga. Poi, quando ha finito, ha rimesso la macro al suo posto, copia-incolla tutto quel codice e ripristina manualmente tutti i '\' alla fine della riga. Ora questo è qualcosa che NON DEVI MAI FARE ... MAI:)

    
risposta data 12.06.2013 - 18:20
fonte
1

La cosa è chiamata 'internal include guard', ed è pratica comune - se fatta bene. Il tuo piccolo esempio riesce ad avere due errori:

  • la guardia deve essere piena: dalla prima all'ultima riga. Niente prima e dopo.
  • che inizia con il carattere di sottolineatura + la lettera maiuscola è riservata all'implementazione, quindi non è corretto da usare, rendilo MYFILE_H_INCLUDED_, o meglio come fanno i compilatori, aggiungi un GUID. Come non deve essere ripetuto in un diverso file .h. Sicuramente usa

#pragma once è migliore se supportato e può essere combinato con l'include guard.

Poiché il nome della macro non è usato per nient'altro, non avrà i suoi problemi comuni; anche ad eccezione del pragma non esiste un modo reale per consentire l'inclusione multipla di intestazioni, e questo è abbastanza necessario.

    
risposta data 12.06.2013 - 17:56
fonte

Leggi altre domande sui tag