Menu
CoddyTech

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ışan ö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ı, sınıfla aynı ada sahiptir ve önüne 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 nesneleri kapsam dışına çıkar
  • Yığın üzerinde 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ı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ız, 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

Yok olan kullanıcı oturumlarını izleyen ve nesneler yok edildiğinde, kapsam dışına çıksalar veya açıkça silinseler bile 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 (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
    • Bir kullanıcı adı, oturum kimliği ve günlük boyutu alan bir kurucu. Kurucu, 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 (geçerli konumu dahili olarak izleyen) bir logActivity(int activityCode) yöntemi; günlük zaten doluysa çağrı yok sayılır, böylece sayı günlük boyutunu hiçbir zaman aşmaz
    • 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:
    • Kıvrımlı parantezleri { } kullanarak bir kapsam bloğu oluşturun ve bunun içinde, girilen kullanıcı adı, 101 oturum kimliği ve girilen günlük boyutuyla stack üzerinde ayrılmış bir Session oluşturun. 1 ve 2 kodlarıyla iki etkinlik 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
    • new kullanarak kullanıcı adı "Guest", oturum kimliği 202 ve günlük boyutu 3 olan heap üzerinde ayrılmış bir Session oluşturun. 5 koduyla bir etkinlik kaydedin, "Heap session activities: <count>" yazdırın ve ardından onu açıkça delete edin.
    • Silme işleminden sonra "Heap session destroyed" yazdırın

Bu görev, 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. Bellek sızıntılarını önlemek için her iki yol da 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 dahil edin.

Kendin dene

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

using namespace std;

int main() {
    // Girişi 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ığında ayrılmış bir Session oluştur
    //   - Kodları 1 ve 2 olan iki etkinlik kaydet
    //   - Print "Stack session activities: <count>"
    // Blok sona erdiğinde yıkıcı otomatik olarak çalışır
    
    // TODO: After the block, print "Stack session destroyed"
    
    // TODO: new kullanarak heap'te ayrılmış bir Session oluştur
    //   - Kullanıcı adı: "Guest", oturum kimliği: 202, log boyutu: 3
    //   - Kod 5 ile bir etkinlik 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