top of page

C++ Dilinde Explicit Constructor

  • Writer: Yusuf Hançar
    Yusuf Hançar
  • Aug 10, 2023
  • 3 min read

C++ dilinde sınıfların özel üye fonksiyonlarından ve programcıyla derleyiciye göre yazılmaları ve kullanımlarından bahsettik. Bunlardan 'constructor' denilen bu kurucu işlevler ihtiyaca göre implicitly yani derleyici tarafından ya da programcı tarafından yazılmaktadır. Derleyicilerin bu ihtiyaçları belirledikten sonra yazdıkları işlevler eğer gereklilikleri karşılıyorsa bunları programcının yazmaması daha verimli bir tasarım olacaktır. Ancak bazı senaryolarda bu kurucu işlevleri bizim yazmamız ve bunun bağımlılıklarını da belirlememiz gerekecektir.

Bu yazımızda explicit contructor fonksiyonunu ve yapısını inceleyeceğiz. Sınıfların (çoğunlukla) tek parametreli kurucu işlevleri explicit olarak yazılmaktadırlar. Tek parametre ile çağrı yapıldığında otomatik olarak tür dönüşümünü engellemek için yazılmaktadır. Yani primitive(int, double..) bir türden sınıf türüne dönüşüme otomatik olarak izin verilmeyecektir. Copy imitialization yapıldığında sentax hatası alınacaktır.


class SmartCode {  
public : 
    explicit SmartCode(int val)  
    { 
        cout << "SmartCode ctor this : " << this << endl;   
    } 

    ~SmartCode()  
    { 
        cout << "SmartCode dtor this : " << this << endl;     
    } 
};

int main() 
{  
    SmartCode sc = 23; 
}
*****************************
AÇIKLAMA: Burada işlem copy initialization yapılmaktadır ve hatalı kullanımdır.
*****************************
CEVAP: syntax error
*****************************

Yukarıdaki örnekte görüldüğü gibi kurucu işlev explicit olduğu için tür dönüşümününde otomatik olarak değil explicit olarak yapılması istenmektedir. Yani operator kullanılarak gerçekleştirilecektir. Burada explicit anahtar sözcüğü static gibi bildirimde olacak, tanımda olmayacaktır. İstisnai durumlar haricinde gerekmedikçe tek parametreli kurucu işlevler için explicit kullanmak faydalı olacaktır.

İstisnai durum string sınıfının 'const char *' parametreli kurucu işlevi verilebilir!
explicit basic_string(const char* val);
*****************************
AÇIKLAMA: Bu constructor C dilindeki gibi bir null karakter dizi alarak bir string nesnesi oluşturur. Bu kurucu işlev explicit olarak tanımlanmamıştır. Yani istenmeyen otomatik dönüşümlere neden olabilmektedir.
*****************************
CEVAP: 
*****************************
#include <iostream>
#include <string>

using namespace std;   // çok tercih edilmemelidir...:)

void show_str(const string& str) 
{
    cout << str << endl;
}

int main() 
{
    show_str("SmartCode");
}
*****************************
AÇIKLAMA: const char* türünden std::string türüne dönüşüm açıkça belirtilmemiştir.
*****************************
CEVAP: 
*****************************

C++11 yani modern C++ öncesinde bu explicit anahtar sözcüğü sadece kurucu işlevler için kullanılırdı. Ancak modern C++ ile artık tür dönüştürme içinde kullanılabilmektedir.


class SmartCode {  
private :
    int m_sc{ 0 };  

public :  
    SmartCode() {}  

    explicit SmartCode(int val) : m_sc{val} {}  
};

int main() 
{  
    SmartCode tmp;  
    int ival = 23;  

    tmp = SmartCode{ ival };     
}
*****************************
AÇIKLAMA: geçici nesne oluşturarak bu işlem geçerli olabilir.
*****************************
CEVAP: geçerli
*****************************
class SmartCode {  
private :
    int m_sc{ 0 };  

public :  
    SmartCode() {}  

    explicit SmartCode(int val) : m_sc{val} {}  
};

int main() 
{  
    SmartCode tmp;  
    int ival = 23;  

    tmp = static_cast<SmartCode>(ival);  
}
*****************************
AÇIKLAMA: cast ederek bu dönüşüm sağlanabilmektedir.
*****************************
CEVAP: geçerli
*****************************

  • Yukarıda da ifade ettiğimiz gibi copy initialization engellenir ancak direct veya brace initialization geçerlidir.

class SmartCode {  
private :
    int m_sc{ 0 };  

public :  
    SmartCode() {}  

    explicit SmartCode(int val) : m_sc{val} {}  
};

int main() 
{  
    SmartCode tmp(23);    
}
*****************************
AÇIKLAMA: direct initialization
*****************************
CEVAP: geçerli
*****************************
class SmartCode {  
private :
    int m_sc{ 0 };  

public :  
    SmartCode() {}  

    explicit SmartCode(int val) : m_sc{val} {}  
};

int main() 
{  
    SmartCode tmp{23};    
}
*****************************
AÇIKLAMA: brace initialization
*****************************
CEVAP: geçerli
*****************************
class SmartCode { 
public : 
    explicit SmartCode(int) {}                     
}; 

void smart_func(SmartCode sc)
{
}

int main() 
{ 
    smart_func(23);                                
}
*****************************
AÇIKLAMA: explicit olduğu için fonksiyona parametre olarak gönderemeyiz.
*****************************
CEVAP: syntax error
*****************************
class SmartCode { 
public : 
    explicit SmartCode(int) {}                     
}; 

SmartCode smart_func()
{
    return 23;
}

int main() 
{                               
}
*****************************
AÇIKLAMA: explicit olduğu için fonksiyondan döndürülen int sınıf türüne dönüştürülemediği için hatalıdır.
*****************************
CEVAP: syntax error
*****************************
ree

 
 
 

Recent Posts

See All
C++ Dilinde [[nodiscard]] attribute

C++’ta [[attribute]] (öznitelik) mekanizması, kod hakkında ek bilgi sağlayarak derleyicinin uyarılar vermesine, belirli optimizasyonlar...

 
 
 
C++ Dilinde constinit

C++20'de tanıtılan önemli bir özellik `constinit`'dir; bu özellik, statik depolama süresine sahip değişkenlerin derleme zamanında...

 
 
 

Comments


bottom of page