The Rule of Zero

06:44
"The Rule of Zero" kuralı sınıfınıza ait destructor, copy constructor, move constructor, copy assignment operator ve move assignment operator fonksiyonlarının hiçbirinin doğrudan bizim tarafımızdan tanımlanmaması anlamına gelmektedir. Peki ne zaman? bu kurala uymak gerekir. Bu noktada önce iki ayrıma dikkat etmek gerekir:

  • Yukarıda bahsi geçen özel fonksiyonlardan herhangi bir fonksiyonu tanımlamaktan kaçınabiliyorsanız, kaçının. Bu sayede hiçbirinin tanımlanmasına gerek kalmıyorsa buna kısaca "Rule of Zero" denilmektedir.
  • Yukarıda bahsi geçen özel fonksiyonlardan herhangi bir fonksiyonu tanımlıyorsanız tamamını tanımlayın, delete ediyorsanız tamamını delete edin. Buna kısaca "Rule of Five" denilmektedir.
Yukarıda iki kuraldan bizi ilgilendiren kısım olan Rule of Zero için şu denilebilir ki; tanımlamaktan kaçabiliyorsanız tanımlamayın. Peki C++ için bu idiomlar neden vardır? veya arka planda neyi ilgilendiriyor? derseniz karşımıza alt seviye dillerde önemli bir sorun olan kaynak yönetimi çıkmaktadır. C++ için Garbage Collector gibi bir yapı olmadığından dolayı kaynakların yönetimi nasıl olacak? sorusuna idiomlar ile çözüm getirilmeye çalışılmıştır. Bu noktada şunu da belirtmeliyiz ki kaynak yönetimi için C'de yer alan raw pointer'lar asla kullanılmamalıdır.  Ve bir C++ programcısı perspektifinden sistemdeki kaynak yönetimi söz konusu olduğunda, nesneleri dört biçimde kategorize edebiliriz:
  • Taşınabilen ve kopyalanabilen nesneler
  • Kopyalanabilen fakat taşınamayan nesneler
  • Taşınabilen fakat kopyalanamayan nesneler
  • Ne kopyalanabilen ne de taşınabilen nesneler
Bu nesnelerin tipine göre sınıf tanımlarında aşağıdaki fonsiyonların tanımlanması ya da delete edilmesi gerekmektedir. Bu fonksiyonlar;
  • Copy constructor
  • Copy assignment operator
  • Move constructor
  • Move assignment operator
Aşağıdaki örnekte Rule of Zero kuralına uygun olarak Car sınıfı tanımlanırken hiçbir özel fonksiyon tanımlaması yapılmamıştır. Ve kaynak yönetimi doğrudan compilerın yazdığı koda havale edilmiştir.
 

Aşağıdaki örnekte sınıfımızın move/copy constructible ya da assignable olup olmadığını incelemeye çalıştık.


Bu yazı Rule of Three/Five yazısıyla devam edilecektir.

Note:

  • default constructor:   X()
  • copy constructor:   X(const X&)
  • copy assignment:   operator=(const X&)
  • move constructor:   X(X&&)
  • move assignment:   operator=(X&&)
  • destructor:   ~X()