C++'da, bir yapıcı bir argüman ile çağrılabiliyorsa, varsayılan olarak implicit (açık olmayan) olarak kabul edilir. Bu tür bir yapıcı, açık olmayan tür dönüşümleri için kullanılabilir. Bunu önlemek için explicit anahtar kelimesi kullanılır.
explicit yapıcılar açık olmayan dönüşümleri yasaklar.Explicit kullanmak, işlevlere türü uyuşmayan bir argüman geçirilmesi veya bir değişkenin başlatılması gibi beklenmedik dönüşümleri önlemeye yardımcı olur.
Örnek:
struct Foo { explicit Foo(int x) { /* ... */ } }; Foo a = 10; // Hata, explicit açık olmayan başlatmayı yasaklar Foo b(10); // Tamam
Eğer explicit olmasaydı, Foo a = 10; ifadesi geçerli olurdu ve beklenmeyen hatalara yol açabilirdi.
Soru: Explicit olarak ilan edilen tüm yapıcılar, = ile başlatma sırasında çağrılamaz mı?
Sık yanıt: Evet, explicit her türlü = ile başlatmayı yasaklar.
Doğru yanıt: explicit yalnızca açık olmayan dönüşümleri yasaklar. Direct initialization (ClassName obj(param);) ile explicit yapıcı çağrılabilir. Kopyalama ile başlatma (ClassName obj = param;) ile çağrılamaz.
Örnek:
struct A { explicit A(int) {} }; A x = 1; // Hata A y(1); // Tamam
Hikaye: Projede, türler aracılığıyla başlatmaya izin veren bir yapıcı yazıldı, bu da işlev argümanlarının beklenmedik otomatik dönüşümlerine yol açtı. Bu, gizli hataların ortaya çıkmasına ve hata ayıklamanın zorlaşmasına yol açtı.
Hikaye: Bir geliştirici konteynerin yapıcısı için explicit koymadı ve varsayılan yapıcı aniden başka türler atanırken veya geçirilirken çağrılmaya başladı. Sonuç — nesne oluşturma mantığında yanlışlıklar ve öngörülemeyen davranışlar.
Hikaye: Tecrübesiz bir programcı explicit yapıcıyı ilan etti, ancak parantez ile direct initialization'ın çalıştığını görünce şaşırdı ve explicit'in bunu da engellediğini düşündü. Bu, güvenli tasarım kalıplarını kullanmamaya ve projede gereksiz koda yol açtı.