Domanda

DISCLAIMER: Non faccio C ++ da un po 'di tempo ...

Oggigiorno è comune decorare le dichiarazioni di metodi / funzioni C / C ++ per migliorare la leggibilità?

Esempio di greggio:

void some_function(IN int param1, OUT char **param2);

con le macro IN e OUT definite con un corpo vuoto (vale a dire una documentazione leggera se si intende in questo esempio). Ovviamente capisco che questo va in qualche modo parallelamente al & Quot; blocco dei commenti doc & Quot; associato al metodo / funzione.

Potresti fornire altri esempi ... supponendo che questo argomento sia utile alla comunità. Per favore tieni presente che l'esempio sopra è proprio quello che è.

È stato utile?

Soluzione

Non apprezzerei tale decorazione.

Molto meglio usare const, riferimenti e riferimenti costanti, come in

void some_function(AClass const &param1, AnotherClass &param2)

Di solito int viene passato per valore e non per riferimento, quindi ho usato AClass e AnotherClass per l'esempio. Mi sembra che aggiungere empy IN e OUT sia fonte di distrazione.

Altri suggerimenti

Le intestazioni di Windows fanno esattamente questo. Vedere Annotazioni intestazione per l'elenco completo di annotazioni utilizzate. Ad esempio & Quot;

DWORD
WINAPI
GetModuleFileName(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
    __in DWORD nSize
    );

Per questa funzione, hModule è un parametro di input facoltativo, lpFilename è un parametro di output che memorizza un massimo di nSize elementi di carattere e che conterrà (il valore di ritorno della funzione) +1 elementi di carattere in al ritorno, e <=> è un parametro di input.

Ai fini della documentazione, è sufficiente un blocco di commenti ben scritto, quindi non servono a nessuno scopo. Inoltre, alcuni parser di commenti di documentazione hanno una sintassi speciale proprio per una cosa del genere; ad esempio, dato Doxygen, potresti scrivere:

/**
 * @param[in]  param1 ...
 * @param[out] param2 ...
 **/
void some_function(int param1, char **param2);

Penso che questa sia una cattiva idea. Soprattutto dal momento che chiunque può venire e definire le macro IN / OUT e lasciarti in grande difficoltà.

Se vuoi davvero documentarlo inserisci commenti.

void some_function(/* IN */ int param1, /* OUT */ char **param2);

Anche perché usare un out quando un valore di ritorno funzionerà bene.
Inoltre preferirei usare pass by ref e const ref per indicare le mie intenzioni. Anche il compilatore ora fa relativamente bene l'ottimizzazione dell'intento quando il tuo codice è corretto.

void some_function(/* IN */ int const& param1, /* OUT */ char*& param2);
// OK for int const& is kind of silly but other types may be usefull.

Non in C ++, non ho fatto C in modo professionale ma almeno in C ++ il tipo di parametri è autoesplicativo:

void f( std::string const & ); // input parameter
void f( std::string );         // input parameter again (by value)
void f( std::string& );        // in/out parameter
std::string f();               // output

Che insieme agli strumenti di documentazione in-code (doxygen) in cui aggiungi un po 'di contesto ai parametri (quali valori sono previsti o inaccettabili dalla funzione, come la funzione cambia gli oggetti passati ...

Informazioni sui puntatori: tendiamo a limitare i puntatori non elaborati nelle nostre interfacce dei metodi. Se necessario, possono essere utilizzati, ma in generale dovrebbero essere preferiti i puntatori intelligenti. Inoltre, la semantica della proprietà viene dalla scelta del puntatore intelligente: shared_ptr & Lt; & Gt; per la responsabilità condivisa diluita (o quando necessario), auto_ptr < > / unique_ptr < > per singola proprietà (di solito come valore di ritorno da fabbriche, locali o attributi dei membri) ...

Provo a usare:

  • Valori per parametri di input o riferimenti se sono grandi
  • Riferimenti per i parametri out
  • Puntatori per assegnare la proprietà alla funzione chiamata

Il più delle volte è davvero facile vedere quali sono i parametri IN o OUT, ovviamente i nomi propri nella dichiarazione sono una buona documentazione.

Trovo fastidiosi quei componenti aggiuntivi IN, OUT.

L'ho visto, ma non credo che direi che è " comune. "

L'API Win32 (C non C ++) usa qualcosa di simile:

WINADVAPI
BOOL
WINAPI
CreateProcessWithLogonW(
    __in        LPCWSTR lpUsername,
    __in_opt    LPCWSTR lpDomain,
    __in        LPCWSTR lpPassword,
    __in        DWORD dwLogonFlags,
    __in_opt    LPCWSTR lpApplicationName,
    __inout_opt LPWSTR lpCommandLine,
    __in        DWORD dwCreationFlags,
    __in_opt    LPVOID lpEnvironment,
    __in_opt    LPCWSTR lpCurrentDirectory,
    __in        LPSTARTUPINFOW lpStartupInfo,
    __out       LPPROCESS_INFORMATION lpProcessInformation
      );

Nel caso di Visual C ++ 2005 e compilatori successivi, questi in realtà corrispondono a dichiarazioni come __$allowed_on_parameter e vengono controllati al momento della compilazione.

L'unica cosa peggiore di questa è stata vista molto tempo fa in un programma C scritto da Pascal dev:


#define begin {
#define end   }

int main( int argc, char* argv[] )
begin
  ...
end

Non l'ho mai visto prima. Penso che sarebbe meglio inserire informazioni come questa nei commenti.

Ho visto l'utilizzo dei prefissi i_, o_, io_ oltre alle informazioni nei tipi di parametro:

void some_function(int i_param1, char** o_param2, int& io_param3);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top