Menu
CoddyTech

Yıkıcıları Derinlemesine İnceleme

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 24 / 104.

Yıkıcı, bir nesne yok edildiğinde otomatik olarak çalışan özel bir üye işlevidir. Temel görevi, nesnenin ömrü boyunca edindiği dinamik olarak ayrılmış bellek, dosya tanıtıcıları veya ağ bağlantıları gibi kaynakları serbest bırakmaktır.

Yıkıcı, sınıfla aynı ada sahiptir ve başına bir tilde işareti ~ eklenir. Parametre almaz ve dönüş türü yoktur:

class FileHandler {
    std::string filename;
    int* buffer;
public:
    FileHandler(std::string name, size_t size) 
        : filename(name), buffer(new int[size]) {
        std::cout << "Opening " << filename << "\n";
    }
    ~FileHandler() {
        delete[] buffer;
        std::cout << "Closing " << filename << "\n";
    }
};

Yıkıcılar şu durumlarda otomatik olarak çağrılır:

  • Yığın nesnelerin kapsamı sona erer
  • Heap'te ayrılmış bir nesne üzerinde delete çağrılır
  • Geçici bir nesnenin yaşam süresi sona erer
void example() {
    FileHandler f1("data.txt", 100);    // Yapıcı çağrıldı
    FileHandler* f2 = new FileHandler("log.txt", 50);
    delete f2;                           // f2 için yıkıcı çağrıldı
}   // f1 için yıkıcı çağrıldı (kapsam dışına çıkar)

Yapıcılardan farklı olarak, bir sınıfın yalnızca bir yıkıcısı olabilir. Onu aşırı yükleyemezsin.

Bir tane tanımlamazsan, derleyici özel bir şey yapmayan varsayılan bir yıkıcı oluşturur; yalnızca her üyeyi yok eder. Kaynakları yöneten sınıflar için bellek sızıntılarını önlemek amacıyla kendi yıkıcını yazmalısın.

challenge icon

Görev

Kolay

Etkin kullanıcı oturumlarını takip eden ve nesneler yok edildiğinde, ister kapsam dışına çıksın ister açıkça silinsin, yıkıcıların kaynakları otomatik olarak nasıl temizlediğini gösteren bir oturum yöneticisi oluşturalım.

Kodunu düzenlemek için iki dosya oluşturacaksın:

  • Session.h: Dinamik olarak ayrılmış veriler içeren etkin bir kullanıcı oturumunu temsil eden bir Session sınıfı tanımla. Sınıfında şunlar bulunmalı:
    • Özel üyeler: bir username (string), bir sessionId (int) ve kullanıcı eylemlerini izleyen activityLog adlı bir tamsayı dizisine işaretçi; ayrıca dizinin boyutu için bir logSize
    • Kullanıcı adı, oturum kimliği ve günlük boyutunu alan bir kurucu. Bu kurucu, etkinlik günlüğü dizisini heap belleğinde ayırmalı, tüm elemanları 0 olarak başlatmalı ve "Session <sessionId> started for <username>" yazdırmalı
    • Ayrılmış belleği serbest bırakan ve "Session <sessionId> ended for <username>" yazdıran bir yıkıcı
    • Etkinlik kodunu bir sonraki kullanılabilir slota kaydeden bir logActivity(int activityCode) metodu (geçerli konumu dahili olarak takip et); günlük zaten doluysa çağrı yok sayılır, böylece sayı hiçbir zaman günlük boyutunu aşmaz
    • Kaç etkinliğin günlüğe kaydedildiğini döndüren bir getActivityCount() metodu
    • Kullanıcı adını döndüren bir getUsername() metodu
  • main.cpp: Farklı senaryolarda yıkıcıların davranışını göster. Girdiden bir kullanıcı adı ve günlük boyutu oku (her biri ayrı bir satırda), ardından:
    • Süslü parantezlerle { } bir kapsam bloğu oluştur ve bloğun içinde, girdi olarak verilen kullanıcı adı, 101 oturum kimliği ve girdi olarak verilen günlük boyutuyla stack üzerinde ayrılmış bir Session oluştur. 1 ve 2 kodlarıyla iki etkinlik kaydet, ardından "Stack session activities: <count>" yazdır. Blok sona erdiğinde yıkıcı otomatik olarak çalışmalı.
    • Bloktan sonra "Stack session destroyed" yazdır
    • new kullanarak heap belleğinde ayrılmış bir Session oluştur; kullanıcı adı "Guest", oturum kimliği 202 ve günlük boyutu 3 olsun. 5 koduyla bir etkinlik kaydet, "Heap session activities: <count>" yazdır, ardından nesneyi açıkça delete et.
    • Silme işleminden sonra "Heap session destroyed" yazdır

Bu görev, yıkıcıların çağrılmasının iki temel yolunu gösterir: stack nesneleri kapsam dışına çıktığında otomatik olarak ve heap nesnelerini sildiğinde elle. Bellek sızıntılarını önlemek için her iki durumda da dinamik olarak ayrılmış etkinlik günlüğü düzgün şekilde serbest bırakılmalıdır.

#include "Session.h" kullanarak başlık dosyanı main.cpp dosyasına ekle.

Kendin dene

#include <iostream>
#include <string>
#include "Session.h"

using namespace std;

int main() {
    // Girdiyi oku
    string username;
    int logSize;
    getline(cin, username);
    cin >> logSize;
    
    // TODO: Süslü parantezlerle { } bir kapsam bloğu oluştur
    // Bloğun içinde:
    //   - Girilen username, oturum ID'si 101 ve girilen günlük boyutuyla yığında ayrılmış bir Session oluştur
    //   - 1 ve 2 kodlu iki etkinliği kaydet
    //   - "Stack session activities: <count>" yazdır
    // Blok sona erdiğinde yıkıcı otomatik olarak çalışır
    
    // TODO: Bloktan sonra "Stack session destroyed" yazdır
    
    // TODO: new kullanarak dinamik bellekte ayrılmış bir Session oluştur
    //   - Kullanıcı adı: "Guest", oturum ID'si: 202, günlük boyutu: 3
    //   - 5 kodlu bir etkinliği kaydet
    //   - "Heap session activities: <count>" yazdır
    //   - Oturumu sil
    
    // TODO: Silme işleminden sonra "Heap session destroyed" yazdır
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C++ derleyicisi