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)
{
}
Obie działają; jaki jest standardowy sposób i dlaczego ?
c++
syntax
optional-parameters
httpinterpret
źródło
źródło
b
zostanie zdefiniowany wiele razy, raz dla każdej jednostki kompilacji, która zawieralib.h
, czy to prawda?b
jest definiowana raz dla każdego.cpp
pliku zawierającego nagłówek. Ale to w porządku, ponieważ masz tylko jedną deklaracjęAdd
funkcji.W C ++ wymagania stawiane argumentom domyślnym w zakresie ich umiejscowienia na liście parametrów są następujące:
Domyślny argument dla danego parametru należy podać nie więcej niż raz. Podanie go więcej niż raz (nawet z tą samą wartością domyślną) jest niedozwolone.
Parametry z domyślnymi argumentami muszą tworzyć ciągłą grupę na końcu listy parametrów.
Mając to na uwadze, w C ++ możesz „powiększać” zestaw parametrów, które mają domyślne argumenty z jednej deklaracji funkcji do następnej, o ile powyższe wymagania są stale spełniane.
Na przykład możesz zadeklarować funkcję bez domyślnych argumentów
void foo(int a, int b);
Aby wywołać tę funkcję po takiej deklaracji, musisz jawnie określić oba argumenty.
Później (niżej) w tej samej jednostce tłumaczeniowej możesz ponownie zadeklarować ją ponownie, ale tym razem z jednym domyślnym argumentem
void foo(int a, int b = 5);
i od tego momentu możesz to wywołać za pomocą tylko jednego wyraźnego argumentu.
Dalej możesz zadeklarować go ponownie, dodając jeszcze jeden domyślny argument
void foo(int a = 1, int b);
i od tego momentu możesz go wywoływać bez wyraźnych argumentów.
Pełny przykład może wyglądać następująco
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) { // ... }
Jeśli chodzi o kod w twoim pytaniu, oba warianty są całkowicie prawidłowe, ale mają różne znaczenie. Pierwszy wariant od razu deklaruje domyślny argument dla drugiego parametru. Drugi wariant początkowo deklaruje twoją funkcję bez domyślnych argumentów, a następnie dodaje jeden dla drugiego parametru.
Efekt netto obu deklaracji (tj. Sposób, w jaki jest to postrzegane przez kod następujący po drugiej deklaracji) jest dokładnie taki sam: funkcja ma domyślny argument dla drugiego parametru. Jeśli jednak uda Ci się wcisnąć jakiś kod między pierwszą a drugą deklaracją, te dwa warianty będą się zachowywać inaczej. W drugim wariancie funkcja nie ma domyślnych argumentów między deklaracjami, więc będziesz musiał jawnie określić oba argumenty.
źródło
void foo(int a = 1, int b)
aby zadziałało, musi zostać zadeklarowane późniejvoid foo(int a, int b = 5)
. Tak, to zadziała. I nie, to nie jest błąd składniowy. g ++ 4.5.3 skompiluje to doskonale.int foo(int)
. Stwierdzam, że mogę pisaćint foo(int=5)
ponownie, pomijając nazwy parametrów. Jak dotąd nikt o tym nie wspomniał.Pierwsza metoda byłaby lepsza od drugiej.
Dzieje się tak, ponieważ plik nagłówkowy pokaże, że parametr jest opcjonalny i jaka będzie jego wartość domyślna. Dodatkowo zapewni to, że wartość domyślna będzie taka sama, niezależnie od implementacji odpowiedniego pliku .cpp.
W drugim przypadku nie ma gwarancji wartości domyślnej drugiego parametru. Wartość domyślna może się zmienić w zależności od tego, jak zaimplementowano odpowiedni plik .cpp.
źródło
Domyślne argumenty należy określić przy pierwszym wystąpieniu nazwy funkcji - zwykle w prototypie funkcji. Jeśli prototyp funkcji zostanie pominięty, ponieważ definicja funkcji służy również jako prototyp, wówczas domyślne argumenty powinny zostać określone w nagłówku funkcji.
źródło