Menu
Coddy logo textTech

Yıkıcılara Derinlemesine Bakış

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ıştırılan özel bir üye işlevidir. Temel görevi, nesnenin yaşam süresi 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ının adı sınıfla aynıdır ve başına bir tilde ~ 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";
    }
};

Yok ediciler şu durumlarda otomatik olarak çağrılır:

  • Yığın nesneleri kapsam dışına çıkar
  • Yığın üzerinde ayrılmış bir nesne için delete çağrılır
  • Geçici bir nesnenin yaşam süresi sona erer
void example() {
    FileHandler f1("data.txt", 100);    // Kurucu ç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ıların aksine, bir sınıfın yalnızca bir yıkıcısı olabilir. Onu aşırı yükleyemezsiniz.

Bir tane tanımlamazsan, derleyici özel bir işlem 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ızı yazmalısınız.

challenge icon

Görev

Kolay

Etkin kullanıcı oturumlarını izleyen ve nesneler yok edildiğinde, kapsam dışına çıksalar ya da açıkça silinseler de yıkıcıların kaynakları otomatik olarak nasıl temizlediğini gösteren bir oturum yöneticisi oluşturalım.

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

  • Session.h: Dinamik olarak ayrılmış veriler içeren etkin bir kullanıcı oturumunu temsil eden bir Session sınıfı tanımlayın. Sınıfınız şunlara sahip olmalıdır:
    • Özel üyeler: bir username (dize), bir sessionId (tamsayı) ve kullanıcı eylemlerini izleyen, activityLog adlı bir tamsayı dizisine işaretçi; ayrıca dizinin boyutu için bir logSize
    • Bir kullanıcı adı, oturum kimliği ve günlük boyutu alan bir oluşturucu. Oluşturucu, etkinlik günlüğü dizisini heap üzerinde ayırmalı, tüm öğeleri 0 olarak başlatmalı ve "Session <sessionId> started for <username>" yazdırmalıdır
    • Ayrılan belleği serbest bırakan ve "Session <sessionId> ended for <username>" yazdıran bir yıkıcı
    • Etkinlik kodunu bir sonraki kullanılabilir yuvaya kaydeden bir logActivity(int activityCode) yöntemi (geçerli konumu dahili olarak izleyin)
    • Günlüğe kaç etkinlik kaydedildiğini döndüren bir getActivityCount() yöntemi
    • Kullanıcı adını döndüren bir getUsername() yöntemi
  • main.cpp: Farklı senaryolarda yıkıcı davranışını gösterin. Girdiden bir kullanıcı adı ve günlük boyutu okuyun (her biri ayrı bir satırda), ardından:
    • Süslü parantezlerle { } bir kapsam bloğu oluşturun ve bu bloğun içinde, girdi olarak alınan kullanıcı adı, Session oturum kimliği ve girdi olarak alınan günlük boyutuyla stack üzerinde ayrılmış bir 101 oluşturun. 1 ve 2 kodlarıyla iki etkinlik günlüğe kaydedin, ardından "Stack session activities: <count>" yazdırın. Blok sona erdiğinde yıkıcı otomatik olarak çalışmalıdır.
    • Bloktan sonra "Stack session destroyed" yazdırın
    • Kullanıcı adı Session, oturum kimliği new ve günlük boyutu "Guest" ile 202 kullanarak heap üzerinde ayrılmış bir 3 oluşturun. 5 koduyla bir etkinlik günlüğe kaydedin, "Heap session activities: <count>" yazdırın ve ardından açıkça delete uygulayın.
    • Silme işleminden sonra "Heap session destroyed" yazdırın

Bu alıştırma, yıkıcıların çağrılmasının iki temel yolunu gösterir: stack nesneleri kapsamdan çıktığında otomatik olarak ve heap nesnelerini sildiğinizde manuel olarak. Her iki yol da bellek sızıntılarını önlemek için dinamik olarak ayrılmış etkinlik günlüğünü düzgün şekilde serbest bırakmalıdır.

Başlık dosyanızı #include "Session.h" kullanarak main.cpp dosyasına ekleyin.

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:
    //   - Girdi kullanıcı adıyla, oturum kimliği 101 ve girdi log boyutuyla yığın-ayrılmış bir Session oluştur
    //   - 1 ve 2 kodlarıyla iki aktivite kaydet
    //   - Print "Stack session activities: <count>"
    // Blok bittiğinde, yıkıcı otomatik olarak çalışır
    
    // TODO: After the block, print "Stack session destroyed"
    
    // TODO: new kullanarak öbek-ayrılmış bir Session oluştur
    //   - Kullanıcı adı: "Guest", oturum kimliği: 202, log boyutu: 3
    //   - 5 koduyla bir aktivite kaydet
    //   - Print "Heap session activities: <count>"
    //   - Oturumu sil
    
    // TODO: After deletion, print "Heap session destroyed"
    
    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