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)
{
}
Her ikisi de çalışır; standart yol hangisidir ve neden ?
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)
{
}
Her ikisi de çalışır; standart yol hangisidir ve neden ?
Yanıtlar:
Bildirimi bir başlık dosyasına, tanımı ayrı bir .cpp
dosyaya ve #include
başlığı farklı bir .cpp
dosyaya koyarsanız, farkı görebilirsiniz.
Özellikle varsayalım:
int Add(int a, int b);
int Add(int a, int b = 3) {
...
}
#include "lib.h"
int main() {
Add(4);
}
Derlemesi test.cpp
varsayılan parametre bildirimini görmeyecek ve bir hata vererek başarısız olacaktır.
Bu nedenle, varsayılan parametre tanımı genellikle işlev bildiriminde belirtilir :
int Add(int a, int b = 3);
b
için bir kez tanımlanır . Ama sorun değil, çünkü işlevin yalnızca bir bildirimi var . .cpp
Add
C ++ 'da, parametre listesindeki konumlarına göre varsayılan bağımsız değişkenlere uygulanan gereksinimler aşağıdaki gibidir:
Belirli bir parametre için varsayılan bağımsız değişken bir defadan fazla belirtilmemelidir. Bir kereden fazla belirtmek (aynı varsayılan değerle bile) yasa dışıdır.
Varsayılan bağımsız değişkenlere sahip parametreler, parametre listesinin sonunda bitişik bir grup oluşturmalıdır.
Şimdi, bunu göz önünde bulundurarak, C ++ 'da, yukarıdaki gereksinimler sürekli olarak karşılandığı sürece, işlevin bir bildiriminden diğerine varsayılan argümanlar içeren parametreler kümesini "büyütmenize" izin verilir.
Örneğin, varsayılan bağımsız değişkenler içermeyen bir işlev bildirebilirsiniz
void foo(int a, int b);
Böyle bir bildirimden sonra bu işlevi çağırmak için her iki argümanı da açıkça belirtmeniz gerekir.
Daha sonra (daha aşağı) aynı çeviri biriminde, tekrar beyan edebilirsiniz, ancak bu sefer bir varsayılan bağımsız değişkenle
void foo(int a, int b = 5);
ve bu noktadan sonra, onu sadece bir açık argümanla çağırabilirsiniz.
Daha aşağıda, bir varsayılan argüman daha ekleyerek yeniden ilan edebilirsiniz.
void foo(int a = 1, int b);
ve bu noktadan sonra onu hiçbir açık argüman olmadan çağırabilirsiniz.
Tam örnek aşağıdaki gibi görünebilir
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)
{
// ...
}
Sorunuzdaki koda gelince, her iki değişken de mükemmel şekilde geçerlidir, ancak farklı şeyler ifade ederler. İlk değişken, hemen ikinci parametre için varsayılan bir bağımsız değişken bildirir. İkinci değişken, başlangıçta işlevinizi varsayılan bağımsız değişkenler olmadan bildirir ve ardından ikinci parametre için bir tane ekler.
Her iki bildiriminizin net etkisi (yani ikinci bildirimi izleyen kod tarafından görülme şekli) tamamen aynıdır: işlevin ikinci parametresi için varsayılan bağımsız değişkeni vardır. Bununla birlikte, birinci ve ikinci bildirimler arasında bir miktar kod sıkıştırmayı başarırsanız, bu iki değişken farklı davranacaktır. İkinci varyantta, işlevin bildirimler arasında varsayılan bağımsız değişkenleri yoktur, bu nedenle her iki bağımsız değişkeni de açıkça belirtmeniz gerekir.
void foo(int a = 1, int b)
bu ilan edilmelidir çalışmaya sonra void foo(int a, int b = 5)
. Evet, işe yarayacak. Ve hayır, bu bir sözdizimi hatası değil. g ++ 4.5.3 onu mükemmel bir şekilde derleyecektir.
int foo(int)
. int foo(int=5)
Parametre isimlerini dışarıda bırakarak tekrar yazabileceğimi görüyorum . Henüz kimse bundan bahsetmemiş gibi görünüyor.
Birinci yol ikinciye tercih edilir.
Bunun nedeni, başlık dosyasının parametrenin isteğe bağlı olduğunu ve varsayılan değerinin ne olacağını göstermesidir. Ek olarak, bu, karşılık gelen .cpp dosyasının uygulaması ne olursa olsun, varsayılan değerin aynı olmasını sağlayacaktır.
İkinci şekilde, ikinci parametre için varsayılan bir değerin garantisi yoktur. Varsayılan değer, karşılık gelen .cpp dosyasının nasıl uygulandığına bağlı olarak değişebilir.
b
birden çok kez tanımlanacak, her derleme birimi için bir kez,lib.h
bu doğru mu?