1
int Add (int a, int b = 3);
int Add (int a, int b)
{
}
2)
int Add (int a, int b);
int Add (int a, int b = 3)
{
}
Ambos trabalham; qual é o caminho padrão e por quê ?
1
int Add (int a, int b = 3);
int Add (int a, int b)
{
}
2)
int Add (int a, int b);
int Add (int a, int b = 3)
{
}
Ambos trabalham; qual é o caminho padrão e por quê ?
Respostas:
Se você colocar a declaração em um arquivo de cabeçalho, a definição em um .cpp
arquivo separado e #include
o cabeçalho de um .cpp
arquivo diferente , poderá ver a diferença.
Especificamente, suponha:
int Add(int a, int b);
int Add(int a, int b = 3) {
...
}
#include "lib.h"
int main() {
Add(4);
}
A compilação de test.cpp
não verá a declaração de parâmetro padrão e falhará com um erro.
Por esse motivo, a definição de parâmetro padrão geralmente é especificada na declaração da função :
int Add(int a, int b = 3);
b
é definido uma vez para cada .cpp
arquivo que inclui o cabeçalho. Mas tudo bem, porque você só tem uma declaração da Add
função.
Em C ++, os requisitos impostos aos argumentos padrão em relação à sua localização na lista de parâmetros são os seguintes:
O argumento padrão para um determinado parâmetro deve ser especificado não mais que uma vez. Especificá-lo mais de uma vez (mesmo com o mesmo valor padrão) é ilegal.
Parâmetros com argumentos padrão precisam formar um grupo contíguo no final da lista de parâmetros.
Agora, mantendo isso em mente, em C ++ você pode "aumentar" o conjunto de parâmetros que possuem argumentos padrão de uma declaração da função para a próxima, desde que os requisitos acima sejam continuamente satisfeitos.
Por exemplo, você pode declarar uma função sem argumentos padrão
void foo(int a, int b);
Para chamar essa função após essa declaração, você precisará especificar ambos os argumentos explicitamente.
Posteriormente (mais abaixo) na mesma unidade de conversão, você pode declarar novamente, mas desta vez com um argumento padrão
void foo(int a, int b = 5);
e a partir daí você pode chamá-lo com apenas um argumento explícito.
Mais abaixo, você pode declará-lo novamente, adicionando mais um argumento padrão
void foo(int a = 1, int b);
e a partir deste ponto você pode chamá-lo sem argumentos explícitos.
O exemplo completo pode ter a seguinte aparência
void foo(int a, int b);
int main()
{
foo(2, 3);
void foo(int a, int b = 5); // redeclare
foo(8); // OK, calls `foo(8, 5)`
void foo(int a = 1, int b); // redeclare again
foo(); // OK, calls `foo(1, 5)`
}
void foo(int a, int b)
{
// ...
}
Quanto ao código em sua pergunta, ambas as variantes são perfeitamente válidas, mas significam coisas diferentes. A primeira variante declara um argumento padrão para o segundo parâmetro imediatamente. A segunda variante inicialmente declara sua função sem argumentos padrão e, em seguida, adiciona uma para o segundo parâmetro.
O efeito líquido de ambas as suas declarações (ou seja, a maneira como é visto pelo código que segue a segunda declaração) é exatamente o mesmo: a função possui argumento padrão para o seu segundo parâmetro. No entanto, se você conseguir espremer algum código entre a primeira e a segunda declarações, essas duas variantes se comportarão de maneira diferente. Na segunda variante, a função não possui argumentos padrão entre as declarações, portanto, você precisará especificar ambos os argumentos explicitamente.
void foo(int a = 1, int b)
funcionar, ele deve ser declarado depois void foo(int a, int b = 5)
. Sim, vai funcionar. E não, não é um erro de sintaxe. O g ++ 4.5.3 o compilará perfeitamente.
int foo(int)
. Acho que posso escrever int foo(int=5)
novamente, deixando de fora os nomes dos parâmetros. Ninguém parece ter mencionado isso ainda.
A primeira maneira seria preferida à segunda.
Isso ocorre porque o arquivo de cabeçalho mostrará que o parâmetro é opcional e qual será o valor padrão. Além disso, isso garantirá que o valor padrão seja o mesmo, independentemente da implementação do arquivo .cpp correspondente.
Na segunda maneira, não há garantia de um valor padrão para o segundo parâmetro. O valor padrão pode mudar, dependendo de como o arquivo .cpp correspondente é implementado.
Os argumentos padrão devem ser especificados com a primeira ocorrência do nome da função - normalmente, no protótipo da função. Se o protótipo da função for omitido porque a definição da função também serve como protótipo, os argumentos padrão deverão ser especificados no cabeçalho da função.
b
, será definido várias vezes, uma vez para cada unidade de compilação que incluilib.h
, certo?