C / C ++ / decoração método função
-
22-07-2019 - |
Pergunta
IMPORTANTE: Eu não fiz C ++ por algum tempo ...
É comum hoje em dia para decorar C / C ++ declarações função / método, a fim de melhorar a legibilidade?
void some_function(IN int param1, OUT char **param2);
com as macros IN e FORA definido com um vazio do corpo (ou seja, documentação leve se você quiser, neste exemplo). Claro que eu entendo isso vai um pouco em paralelo com o "doc bloco de comentário" associado com o método / função.
Você poderia fornecer alguns outros exemplos ... assumindo que este tópico é útil para a comunidade. Por favor, ter em mente que o exemplo acima é apenas o que é.
Solução
Eu não gostaria de receber tais decoração.
muito melhor usar const e referências e as referências constantes, como em
void some_function(AClass const ¶m1, AnotherClass ¶m2)
Normalmente int são passados ??por valor e não por referência, então eu usei AClass e AnotherClass para o exemplo. Parece-me que a adição de empy IN e OUT seria distrair.
Outras dicas
cabeçalhos do Windows, na verdade, fazer exatamente isso. Consulte Cabeçalho Anotações para a lista completa de anotações utilizado. Por exemplo, "
DWORD
WINAPI
GetModuleFileName(
__in_opt HMODULE hModule,
__out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
__in DWORD nSize
);
Para esta função, hModule
é um parâmetro de entrada opcional, lpFilename
é um parâmetro de saída que armazenar um máximo de elementos de caráter nSize
e que irá conter (o valor de retorno da função) +1 elementos de caracteres em que sobre o retorno, e nSize
é um parâmetro de entrada.
Para fins de documentação, um bloco de comentário bem escrito é suficiente, pelo que estes não servem qualquer propósito. Além disso, alguns comentário de documentação analisadores têm sintaxe especial para apenas tal coisa a; Por exemplo, dado Doxygen, você poderia escrever:
/**
* @param[in] param1 ...
* @param[out] param2 ...
**/
void some_function(int param1, char **param2);
Eu acho que isso é uma má idéia. Especialmente desde que qualquer um pode vir e definir as macros in / out e deixá-lo em apuros heap.
Se você realmente quer para documentar que colocar comentários dentro deles.
void some_function(/* IN */ int param1, /* OUT */ char **param2);
Além disso, por que usar um fora quando um valor de retorno irá funcionar bem.
Também eu preferiria usar passagem por ref e ref const para indicar minhas intenções. Além disso, o compilador agora faz relativamente boa optimsing para a intenção quando o código é const correta.
void some_function(/* IN */ int const& param1, /* OUT */ char*& param2);
// OK for int const& is kind of silly but other types may be usefull.
Não em C ++, eu não fiz C programação profissionalmente, mas pelo menos em C ++ do tipo dos parâmetros é auto-explicativo:
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
Isso, juntamente com ferramentas de documentar em código (doxygen) onde você adicionar um pouco de contexto para os parâmetros (os valores que são esperados ou inaceitáveis ??pela função, como a função muda o passado em objetos ...
Sobre ponteiros: Nós tendem a limitar ponteiros crus em nossas interfaces de método. Quando necessário, eles podem ser usados, mas em ponteiros inteligentes gerais devem ser preferidos. Então, novamente, a semântica de propriedade vem da escolha de ponteiro inteligente: shared_ptr <> para a responsabilidade compartilhada diluído (ou quando necessário), auto_ptr <> / unique_ptr <> para a posse única (geralmente como valor de retorno de fábricas, moradores ou atributos de membro). ..
Eu tento usar:
- Os valores para os parâmetros de entrada ou referências, se eles são grandes
- As referências para parâmetros de saída
- Ponteiros dar posse ao chamado função
Na maioria das vezes é realmente fácil de ver quais são os parâmetros IN ou OUT, de nomes de curso adequados na declaração são uma documentação boa.
I encontrar aqueles IN, complementos OUT irritante.
Eu já vi isso, mas eu não acho que eu diria que é "comum".
A API Win32 (C não C ++) usa algo semelhante:
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
);
No caso do Visual C ++ 2005 e compiladores posteriores, estes realmente mapear a declarações como __$allowed_on_parameter
e são verificados em tempo de compilação.
A única coisa pior do que isso foi visto há muito tempo em um programa C escrito por dev Pascal:
#define begin {
#define end }
int main( int argc, char* argv[] )
begin
...
end
Eu não vi isso antes. Eu acho que seria melhor colocar a informação como esta nos comentários.
Eu uso serra de prefixos I_, o_, io_ além de informações em tipos de parâmetros:
void some_function(int i_param1, char** o_param2, int& io_param3);