CodeBlanks Logo Icon CodeBlanks

Rule of five

Rule of five ve kaynak yönetimini öğrenirsin.

Rule of five

Rule of five ilkesi der ki: eğer bir sınıf yıkıcı (destructor), kopyalayan yapıcı (copy constructor) veya kopyalayan atama (copy assignment) tanımlıyorsa, muhtemelen beşinin de tanımlanması gerekir.

Bu beş üye şunlardır: ~T() (yıkıcı), T(const T&) (copy constructor), T& operator=(const T&) (copy assignment), T(T&&) (move constructor) ve T& operator=(T&&) (move assignment). Eğer sınıf bir kaynağı yönetiyorsa (ham işaretçi, dosya tanıtıcı) ve yalnızca yıkıcıyı tanımlarsan, kopyalama sığ kopyalama yapar ve çift serbest bırakma hatası oluşur. Bu yüzden beşini birden yazmak en güvenli yoldur.

Rule of zero

Modern C++'ta rule of zero tercih edilir: eğer sınıf yalnızca std::string, std::vector veya akıllı işaretçiler gibi kaynak yöneten üyeler tutuyorsa, hiçbir özel üye tanımlamana gerek yoktur.

Derleyici bu üyeler için otomatik olarak doğru move ve copy işlemleri üretir. Örnek: class Student { std::string name; std::vector<int> grades; }; sınıfı için hiçbir özel üye yazmazsın ve her şey otomatik çalışır. Ham işaretçi kullanırsan rule of five gerekir; akıllı işaretçi kullanırsan rule of zero yeter. Bu yüzden modern C++ ham işaretçilerden kaçınır.

Uygulama Buffer sınıfına move üyeleri ekle

Başlangıç kodundaki Buffer sınıfında yıkıcı, copy constructor ve copy assignment zaten var (rule of five'nin üçü). Move constructor ve move assignment ekle. main içinde std::move ile a'yı b'ye taşı ve b.data'yı std::cout ile yazdır.

Başlangıç kodu

main.cpp
#include <iostream>
#include <string>
#include <utility>

class Buffer {
public:
    std::string data;
    Buffer(std::string d) : data(d) {}
    ~Buffer() {}
    Buffer(const Buffer& other) : data(other.data) {}
    Buffer& operator=(const Buffer& other) { data = other.data; return *this; }
    // Move constructor ve move assignment ekle
};

int main() {
    Buffer a("Merhaba");
    // a'yı b'ye taşı ve b.data'yı yazdır
    return 0;
}

Örnek çözüm

main.cpp
#include <iostream>
#include <string>
#include <utility>

class Buffer {
public:
    std::string data;
    Buffer(std::string d) : data(d) {}
    ~Buffer() {}
    Buffer(const Buffer& other) : data(other.data) {}
    Buffer& operator=(const Buffer& other) { data = other.data; return *this; }
    Buffer(Buffer&& other) : data(std::move(other.data)) {}
    Buffer& operator=(Buffer&& other) { data = std::move(other.data); return *this; }
};

int main() {
    Buffer a("Merhaba");
    Buffer b(std::move(a));
    std::cout << b.data;
    return 0;
}

Beklenen çıktı

Merhaba

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Beş üyeyi rolüne eşle

Kavram Anlamı
~T() Yıkıcı
T(const T&) Copy constructor
T(T&&) Move constructor
T& operator=(T&&) Move assignment

2 Rule of five kaç üyeyi kapsar?

main.cpp
~T(); T(const T&); T(T&&);
T& operator=(const T&); T& operator=(T&&);
  • Üç
  • İki
  • Beş Doğru cevap
  • Yedi

Açıklama: Rule of five beş üyeyi kapsar.

3 Yıkıcı imzası

Soru
~____() { /* kaynağı serbest bırak */ }
Cevap
~Buffer() { /* kaynağı serbest bırak */ }

Açıklama: Yıkıcı ~SınıfAdı() biçiminde yazılır.

Orta seviye bölümündeki tüm dersler