C++11 – Üye fonksiyonlarda ‘default’ ve ‘delete’ manipülasyonu

C++03 standartlarına göre boş bir sınıf tanımlasanız bile derleyici tarafından bir tane default constructor, copy ctor(constructor) ve atama operatörünü (operator=) sizin için oluşturuyordu.

C++11 standartlarıyla beraber direkt olarak derleyicinin bu tarz davranşlarını manipüle etme şansına hakim oluyorsunuz. C++ programlama dilini işte en çok bu yüzden seviyorum, yazılımcıya olabildiğince fazla hareket alanı sağlıyor.

Tipik bir örnek olarak eğer sınıfınıza herhangi bir ctor tanımladığınızda derleyici sizin için ctor tanımlamayacaktır. Aşağıdaki kodu inceleyelim;

#include <iostream>

using namespace std;

class cppturkey
{
public:
cppturkey(int a) {};
};

int main(int argc, char**argv)
{

cppturkey hbk(5); //ok
cppturkey hb; //hata derleyici default ctor oluşturmadığı için:
//main.cpp:23:13: error: no matching function for call to ‘cppturkey::cppturkey()’

return 0;
}

C++11 ile gelen yeni özellikle beraber derleyiciye kardeşim sen yine bana default ctor üret diyebiliyoruz;

#include <iostream>


using namespace std;

class cppturkey
{
public:
cppturkey(int a) {};
cppturkey() = default;
};

int main(int argc, char**argv)
{

cppturkey hbk(5); //ok
cppturkey hb; //ok



return 0;
}

Görüldüğü üzere artık derlerken hata almıyoruz.

cppturkey()  = default;

İfadesini sadece sınıfın tanımına ekleyerek derleyici tarafından oluşturulan default ctor’un her zaman oluşturulmasını sağladık.

Başka bir kullanımı ise, daha önce C++03 zamanıda : ) bir sınıfı kopyalanamaz yapmak için copy ctor’unu ve atama operatörünü private yapılırdı. Şimdi bizim ‘delete’ imiz var hatta operator new’ i de ‘delete’ edebiliriz, Şöyle ki;

#include <iostream>


using namespace std;

class cppturkey
{
public:
cppturkey(int a) {};
cppturkey() = default;
cppturkey(const cppturkey&) = delete;
cppturkey& operator=(const cppturkey&) = delete;
void* operator new(std::size_t) = delete;
void* operator new[](std::size_t) = delete;
};

int main(int argc, char**argv)
{

cppturkey hbk(5); //ok
cppturkey hb(hbk); //hata derleyiciye copy ctor fonksiyonunu oluşturma demiştik : main.cpp:21:19: error: use of deleted function ‘cppturkey::cppturkey(const cppturkey&)’

hb = hbk; // hata derleyiciye atama operatörü fonksiyonunu oluşturma demiştik 🙂 : main.cpp:23:8: error: use of deleted function ‘cppturkey& cppturkey::operator=(const cppturkey&)’

cppturkey *pHbk = new cppturkey[4]; // hata main.cpp:25:34: error: use of deleted function ‘static void* cppturkey::operator new [](std::size_t)’
cppturkey *pHbk = new cppturkey; // hata main.cpp:26:25: error: use of deleted function ‘static void* cppturkey::operator new(std::size_t)’

return 0;
}

‘delete’ anahtar kelimesi otomatik tür dönüşümünü engellemek amacıyla tüm üye fonksiyonlara uygulanabilir, Örneğin;

#include <iostream>


using namespace std;

class cppturkey
{
public:
cppturkey(int a) {};
cppturkey() = default;
cppturkey(const cppturkey&) = delete;
cppturkey& operator=(const cppturkey&) = delete;
void f(int a) {};
void f(double &) = delete;
};

int main(int argc, char**argv)
{

cppturkey hbk(5); //ok
cppturkey hb;

hb.f(5); // ok sorun yok
hb.f(5.); // ok sorun yok, çünkü otomatik olarak 5.0 int türüne dönüştürüldü.

return 0;
}

Ayrıca bu kullanımı fonksiyon şablonlarını (function template) kullanarak genelleştirebiliriz; Örneğin f fonksiyonunu integer türü haricindeki hiçbir argümanla çağıramayalım:

#include <iostream>


using namespace std;

class cppturkey
{
public:
cppturkey(int a) {};
cppturkey() = default;
cppturkey(const cppturkey&) = delete;
cppturkey& operator=(const cppturkey&) = delete;
void f(int a) {};
template<typename T> void f(T) = delete;
};

int main(int argc, char**argv)
{

cppturkey hbk(5);
cppturkey hb;

hb.f(5); // ok sorun yok
hb.f(5.00); // hata: main.cpp:26:14: error: use of deleted function ‘void cppturkey::f(T) [with T = double]’

return 0;
}