---
title: İstisnalar
source: 'https://academia.sh/tr/kurslar/cpp-temelleri/istisnalar'
course: 'C++ Temelleri ve Nesne Tasarımı'
language: tr
updated: '2026-09-26T03:02:46+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Değerle yakalamanın referansla yakalamadan bir kopya fazla ürettiğini sayaçla ölçer'
    - 'Yapımı yarıda kesen bir istisnanın, zaten kurulmuş parçaları yıktığını ama nesnenin kendisini yıkmadığını gözlemler'
    - 'İsimli bir yerel yerine geçici bir nesne fırlatmanın kopya sayısını nasıl azalttığını ölçer'
---

# İstisnalar

Fırlatılan bir nesnenin yakalanırken kaç kez kopyalandığının, yarıda kesilen bir yapımın hangi parçaları yıktığının ve geçici bir nesnenin isimli bir yerelden daha az kopyalandığının ölçümü.

Önceki dört ders normal akışta tamamlanan kurucu, yıkıcı ve sanal çağrıları ölçtü. Bu
ders akışın **yarıda kesildiği** durumu ele alıyor: bir işlev hata fırlattığında
(`throw`), fırlatılan nesne `catch` bloğuna ulaşana kadar bir ya da daha çok kez
kopyalanabiliyor; kesilme bir kurucunun ortasında olduysa, kurulmuş parçalar yıkılıyor
ama nesnenin kendisi hiç yıkılmıyor. Ölçü sorusu: bir ifade kaç kez, hangi nesnenin
kopyasıyla çalışıyor?

## Değerle Yakalama, Referansla Yakalamadan Bir Kopya Fazla Üretiyor

`HataNesnesi`, kopya kurucusunda bir sayaç artırıyor. Aynı isimli yerel nesneyi
fırlatıp bir kez değerle, bir kez referansla yakaladığımızda, sayaç kaç kopya
gösteriyor?

```cpp
// istisna_kopya_sayaci.cpp — deger ile yakalama referansla yakalamadan bir kopya fazla uretiyor
#include <iostream>

class HataNesnesi {
public:
    HataNesnesi() = default;
    HataNesnesi(const HataNesnesi&) { ++kopya_sayaci; }
    static int kopya_sayaci;
};
int HataNesnesi::kopya_sayaci = 0;

void firlat() {
    HataNesnesi h;
    throw h;
}

int main() {
    try {
        firlat();
    } catch (HataNesnesi h) {
        (void)h;
    }
    std::cout << "deger ile yakalamadan sonra kopya sayisi " << HataNesnesi::kopya_sayaci << "\n";

    HataNesnesi::kopya_sayaci = 0;
    try {
        firlat();
    } catch (const HataNesnesi& h) {
        (void)h;
    }
    std::cout << "referansla yakalamadan sonra kopya sayisi " << HataNesnesi::kopya_sayaci << "\n";

    return 0;
}
```

```
deger ile yakalamadan sonra kopya sayisi 2
referansla yakalamadan sonra kopya sayisi 1
```

**CB13.** `throw h;` isimli bir yereli fırlatıyor — istisna depolamasına bir kopya
çıkarıyor (birinci). `catch (HataNesnesi h)` bunu **değerle** yakalayıp ikinci bir
kopya çıkarıyor: toplam **2**. `catch (const HataNesnesi& h)` depolanmış nesneye
doğrudan bağlanıyor, ek kopya çıkarmıyor: toplam **1**. Sınıf **kopya**: değerle
yakalama, referansla yakalamanın işine bir kopya daha ekliyor.

## Yapımı Yarıda Kesen İstisna: Kurulan Parçalar Yıkılıyor, Nesnenin Kendisi Yıkılmıyor

`Bilesik`'in kurucusu iki `AltParca` üyesini kurduktan sonra bir istisna fırlatıyor.
Zaten kurulmuş üyeler yıkılıyor mu? `Bilesik`'in kendi yıkıcısı hiç çalışıyor mu?

```cpp
// istisna_yarida_kesilen_yapim.cpp — kurulan parcalar yikiliyor, nesnenin kendisi hic yikilmiyor
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>

class AltParca {
public:
    explicit AltParca(std::string ad) : ad_(std::move(ad)) {
        std::cout << ad_ << " kuruldu\n";
    }
    ~AltParca() {
        std::cout << ad_ << " yikildi\n";
    }
private:
    std::string ad_;
};

class Bilesik {
public:
    Bilesik() : birinci_("birinci"), ikinci_("ikinci") {
        std::cout << "Bilesik govdesi calisiyor, istisna firlatiliyor\n";
        throw std::runtime_error("yapim hatasi");
    }
    ~Bilesik() {
        std::cout << "Bilesik yikici calisti\n";
    }
private:
    AltParca birinci_;
    AltParca ikinci_;
};

int main() {
    try {
        Bilesik b;
    } catch (const std::exception& e) {
        std::cout << "yakalanan hata: " << e.what() << "\n";
    }
    return 0;
}
```

```
birinci kuruldu
ikinci kuruldu
Bilesik govdesi calisiyor, istisna firlatiliyor
ikinci yikildi
birinci yikildi
yakalanan hata: yapim hatasi
```

**CB14.** `birinci_` ve `ikinci_` üye ilkleme listesinde kuruluyor. Gövdede fırlatılan
istisna kurucuyu yarıda kesiyor: `Bilesik` **hiçbir zaman tamamlanmadı**. Yığıt
çözülürken o ana kadar kurulmuş üyeler ters sırayla yıkılıyor — önce `ikinci_`, sonra
`birinci_` — ama "Bilesik yikici calisti" hiç basılmadı: yıkıcı ancak kurucu
**tamamlanmışsa** çağrılıyor. Sınıf **kopya** burada doğrudan görünmüyor, ama
`catch (const std::exception& e)` referansla yakalayıp ek kopya çıkarmıyor.

## Geçici Bir Nesne, İsimli Bir Yerelden Daha Az Kopyalanıyor

CB13'te isimli bir yerel fırlatılıp değerle yakalanınca kopya sayısı **2** çıktı.
Doğrudan bir geçici (`throw HataNesnesi();`) fırlatılıp yine değerle yakalanırsa bu
sayı değişiyor mu?

```cpp
// istisna_gecici_kopya.cpp — gecici nesne firlatmak isimli yerelden daha az kopyaliyor
#include <iostream>

class HataNesnesi {
public:
    HataNesnesi() = default;
    HataNesnesi(const HataNesnesi&) { ++kopya_sayaci; }
    static int kopya_sayaci;
};
int HataNesnesi::kopya_sayaci = 0;

void firlat_gecici() {
    throw HataNesnesi();
}

int main() {
    try {
        firlat_gecici();
    } catch (HataNesnesi h) {
        (void)h;
    }
    std::cout << "gecici nesne firlatilinca (deger ile yakalama) kopya sayisi "
              << HataNesnesi::kopya_sayaci << "\n";

    return 0;
}
```

```
gecici nesne firlatilinca (deger ile yakalama) kopya sayisi 1
```

**CB15.** `firlat_gecici` isimli bir yerel kurmuyor, doğrudan bir geçici (prvalue)
kurup fırlatıyor; C++17'de bir geçiciden (prvalue) ilklenen istisna nesnesi
kopya kurucu çağrılmadan doğrudan istisna depolamasında kurulur, birinci kopya
düşüyor. Kalan tek kopya değerle yakalamanınki: toplam **1**, CB13'teki **2**'den bir
eksik. Sınıf **kopya**: fırlatılan ifadenin isimli yerel mi geçici mi olduğu, kopya
sayısını değiştiriyor.

## Yığıt Çözülmesi Çok Çerçeveli: Her Katman Kendi Yerellerini Yıkıyor

CB14 tek bir kurucunun içinde yarıda kalan yapımı ölçtü. İstisna birkaç iç içe işlev
çağrısının en derininde fırlatılırsa, ara çerçevelerdeki yerel nesneler de aynı
yığıt-çözülme mekanizmasıyla yıkılıyor mu, ve hangi sırayla?

```cpp
// istisna_yigit_cozulmesi.cpp — cok cerceveli yigit cozulmesinde her cerceve kendi yerellerini ters sirayla yikiyor
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>

class Izleyici {
public:
    explicit Izleyici(std::string ad) : ad_(std::move(ad)) {
        std::cout << ad_ << " kuruldu\n";
    }
    ~Izleyici() {
        std::cout << ad_ << " yikildi (yigit cozulurken)\n";
    }
private:
    std::string ad_;
};

void ucuncu_seviye() {
    Izleyici i3("ucuncu seviye");
    throw std::runtime_error("derinlerde hata");
}

void ikinci_seviye() {
    Izleyici i2("ikinci seviye");
    ucuncu_seviye();
}

void birinci_seviye() {
    Izleyici i1("birinci seviye");
    ikinci_seviye();
}

int main() {
    try {
        birinci_seviye();
    } catch (const std::exception& e) {
        std::cout << "yakalanan hata: " << e.what() << "\n";
    }
    return 0;
}
```

```
birinci seviye kuruldu
ikinci seviye kuruldu
ucuncu seviye kuruldu
ucuncu seviye yikildi (yigit cozulurken)
ikinci seviye yikildi (yigit cozulurken)
birinci seviye yikildi (yigit cozulurken)
yakalanan hata: derinlerde hata
```

**CB35.** Üç çerçevenin yerelleri kuruluş sırasıyla basılıyor, yıkım tersi sırayla:
önce `i3`, sonra `i2`, sonra `i1`. Yığıt çözülmesi `catch`'e ulaşana kadar geçtiği
**her** çerçevenin yerellerini yıkıyor — CB14'ün tek kurucudaki kuralının çağrı
yığıtının tamamına genellenmiş hâli. Sınıf **kopya** görünmüyor, ama düzenek aynı.

## throw; Orijinal Nesneyi Koruyor, throw e; Statik Tipe Sadeliyor

Yakalanan bir istisnayı yeniden fırlatmanın iki yazımı var: parametresiz `throw;` ve
yakalanan değişkeni fırlatan `throw e;`. İkisi aynı istisnayı mı taşıyor dışarıya?

```cpp
// istisna_throw_vs_throw_e.cpp — throw; orijinal tipi koruyor, throw e; parametrenin statik tipine sadeliyor
#include <iostream>
#include <stdexcept>

class TabanHata : public std::runtime_error {
public:
    TabanHata() : std::runtime_error("taban hata") {}
};

class TuremisHata : public TabanHata {
public:
    TuremisHata() = default;
};

void yeniden_firlat_orijinal() {
    try {
        throw TuremisHata();
    } catch (TabanHata&) {
        throw; // yakalanan nesneyi oldugu gibi, dinamik tipiyle yeniden firlatiyor
    }
}

void yeniden_firlat_sadelenmis() {
    try {
        throw TuremisHata();
    } catch (TabanHata& e) {
        throw e; // e'nin statik tipinden (TabanHata) yeni bir nesne kuruyor
    }
}

int main() {
    try {
        yeniden_firlat_orijinal();
    } catch (TuremisHata&) {
        std::cout << "throw; sonrasi TuremisHata olarak yakalandi\n";
    } catch (TabanHata&) {
        std::cout << "throw; sonrasi TabanHata olarak yakalandi\n";
    }

    try {
        yeniden_firlat_sadelenmis();
    } catch (TuremisHata&) {
        std::cout << "throw e; sonrasi TuremisHata olarak yakalandi\n";
    } catch (TabanHata&) {
        std::cout << "throw e; sonrasi TabanHata olarak yakalandi\n";
    }

    return 0;
}
```

```
throw; sonrasi TuremisHata olarak yakalandi
throw e; sonrasi TabanHata olarak yakalandi
```

**CB36.** `throw;` yakalanan nesneyi olduğu gibi yeniden fırlatıyor, dış `catch` onu
hâlâ **`TuremisHata`** olarak yakalıyor — dinamik tip korunuyor. `throw e;` ise
`e`'nin **statik** tipinden (`TabanHata`) yeni bir nesne kuruyor; `catch
(TuremisHata&)` artık eşleşmiyor — CB21'deki nesne dilimlemeyle aynı kök. Sınıf **kopya**:
`throw e;`, orijinalin değil `e`'nin statik tipinden kurulmuş bir kopyayı taşıyor.

## Taban Sınıfa Değerle Yakalama, Türetilmiş İstisnayı Diliyor

`TuremisHata`, `tip()` sanal işlevini yeniden tanımlıyor. Aynı nesne bir kez değerle
bir kez referansla `TabanHata` olarak yakalanınca, `tip()` hangi sürüme ulaşıyor?

```cpp
// istisna_deger_ile_yakalama_dilimleme.cpp — turetilmis istisna tabana deger ile yakalaninca diliniyor, referansla yakalaninca dilinmiyor
#include <iostream>
#include <stdexcept>

class TabanHata : public std::exception {
public:
    virtual const char* tip() const { return "TabanHata"; }
};

class TuremisHata : public TabanHata {
public:
    const char* tip() const override { return "TuremisHata"; }
};

void firlat_turemis() {
    throw TuremisHata();
}

int main() {
    try {
        firlat_turemis();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcatch-value="
    } catch (TabanHata e) { // derleyici burada bilerek deger ile yakalandigini uyariyor, olcum tam da bu davranisi gosteriyor
#pragma GCC diagnostic pop
        std::cout << "deger ile yakalanan nesnenin tip() sonucu: " << e.tip() << "\n";
    }

    try {
        firlat_turemis();
    } catch (const TabanHata& e) {
        std::cout << "referansla yakalanan nesnenin tip() sonucu: " << e.tip() << "\n";
    }

    return 0;
}
```

```
deger ile yakalanan nesnenin tip() sonucu: TabanHata
referansla yakalanan nesnenin tip() sonucu: TuremisHata
```

**CB37.** `catch (TabanHata e)` değerle yakalıyor: nesne `TabanHata` tipinde yeni bir
nesneye kopyalanıyor — CB21'dekine benzer dilimleme, `tip()` **`TabanHata`**'ya
ulaşıyor. `catch (const TabanHata& e)` depolanmış `TuremisHata`'ya doğrudan
bağlanıyor, dilimlemiyor: **`TuremisHata`**. Bu yüzden istisna hiyerarşileri
neredeyse hep **referansla** yakalanır. Sınıf **kopya**: `catch (TabanHata e)`'nin
ürettiği nesne, orijinalin `TabanHata` parçasının bir kopyası.

## Üç İstisna Güvencesi Düzeyi: Güçlü Durumu Korur, Temel Durumu Değiştirebilir

İstisna fırlatan bir işlevden sonra nesnenin durumu üç düzeyden birinde olabilir:
**güçlü güvence** (öncesi duruma dönülür), **temel güvence** (geçerli ama değişmiş
olabilir), **fırlatmama güvencesi** (sıradaki ölçüm). Aynı sınırı aşan iki ekleme
işlevi — biri güçlü biri temel güvenceyle yazılmış — başarısız çağrı sonrası nasıl
farklılaşıyor?

```cpp
// istisna_guvence_duzeyleri.cpp — guclu guvence basarisiz cagridan sonra durumu degistirmiyor, temel guvence degistirebiliyor
#include <iostream>
#include <stdexcept>

class Sayac {
public:
    void guclu_ekle(int miktar) {
        int yeni_deger = deger_ + miktar; // hesap yerel degiskende, deger_ henuz degismedi
        if (yeni_deger > 100) {
            throw std::runtime_error("sinir asildi");
        }
        deger_ = yeni_deger; // yalnizca basari kesinlesince atama yapiliyor
    }

    void temel_ekle(int miktar) {
        deger_ += miktar / 2;             // once yarisi dogrudan uygulaniyor
        if (deger_ + miktar / 2 > 100) {
            throw std::runtime_error("sinir asildi");
        }
        deger_ += miktar / 2;             // sonra kalan yari
    }

    int deger() const { return deger_; }

private:
    int deger_ = 90;
};

int main() {
    Sayac s1;
    try {
        s1.guclu_ekle(20);
    } catch (const std::exception&) {
        std::cout << std::boolalpha
                  << "guclu_ekle basarisiz oldu, deger degisti mi: "
                  << (s1.deger() != 90) << "\n";
    }

    Sayac s2;
    try {
        s2.temel_ekle(20);
    } catch (const std::exception&) {
        std::cout << std::boolalpha
                  << "temel_ekle basarisiz oldu, deger degisti mi: "
                  << (s2.deger() != 90) << "\n";
    }

    return 0;
}
```

```
guclu_ekle basarisiz oldu, deger degisti mi: false
temel_ekle basarisiz oldu, deger degisti mi: true
```

**CB38.** `guclu_ekle` sınır kontrolünü **yerel bir değişkende** yapıp `deger_`'e
yalnız başarı kesinleşince atıyor; `deger_` hiç dokunulmuyor: **false** — güçlü
güvence. `temel_ekle` sınırı **iki adımda** uygulayıp kontrolü aralarına
sıkıştırıyor; fırlatma anında `deger_` zaten kısmen değişmiş: **true** — temel
güvence. Üçüncü düzey sıradaki ölçümde `noexcept` üzerinden ele alınıyor. Sınıf
**kendisi**: fark nesnenin kimliğinde değil, çağrının onu bıraktığı durumda.

## Kopyala, Değiştir, Değiştir-Tokuş Et: Güçlü Güvenceyi Yapıdan Kazanmak

Atama işlecini elle yazmak yerine parametreyi **değerle** alıp bir `takas` işleviyle
değiştirmek de güçlü güvence sağlayan bilinen bir kalıp. Normal atamada ve öz atamada
(`c = c;`) doğru sonucu veriyor mu?

```cpp
// istisna_kopyala_degistir_tokusla.cpp — kopyala-degistir-degistir-tokus et deseni normal atamada ve oz atamada dogru sonucu veriyor
#include <iostream>
#include <string>
#include <utility>

class Tampon {
public:
    explicit Tampon(std::string veri) : veri_(std::move(veri)) {}
    Tampon(const Tampon& diger) : veri_(diger.veri_) {}

    friend void takas(Tampon& a, Tampon& b) noexcept {
        using std::swap;
        swap(a.veri_, b.veri_);
    }

    Tampon& operator=(Tampon diger) { // deger ile aliniyor: kopya cagrinin kendisinde olusuyor
        takas(*this, diger);
        return *this;
    } // diger burada yikiliyor, eski veri_ onunla birlikte gidiyor

    const std::string& veri() const { return veri_; }

private:
    std::string veri_;
};

int main() {
    Tampon a("birinci");
    Tampon b("ikinci");
    a = b;
    std::cout << "atama sonrasi a: " << a.veri() << ", b: " << b.veri() << "\n";

    Tampon c("ucuncu");
    c = c;
    std::cout << "oz atama sonrasi c: " << c.veri() << "\n";

    return 0;
}
```

```
atama sonrasi a: ikinci, b: ikinci
oz atama sonrasi c: ucuncu
```

**CB39.** `operator=(Tampon diger)` parametreyi **değerle** alıyor; `diger` çağrı
sırasında bağımsız bir kopya olarak kuruluyor — kopyalama, gövde çalışmadan **önce**,
fırlayabilecek tek yerde tamamlanıyor. Gövde yalnız `noexcept` `takas`'ı çağırıyor: bu
sıralama güçlü güvenceyi otomatik veriyor, kopyalama başarısız olursa `*this` hiç
değişmez. Öz atamada (`c = c;`) özel bir kontrole gerek kalmıyor, `diger` bağımsız bir
kopya olduğu için sonuç yine **ucuncu**. Sınıf **kopya**: güvence, atamadan önce ayrı
bir kopya çıkarılmasına dayanıyor.

## noexcept: Fırlatmama Sözleşmesi ve Yeniden Ayırmada Taşıma Seçimi

`std::vector` kapasitesini aştığında yeniden ayırma yapıp eski elemanları taşıyor ya
da kopyalıyor. Standart, taşıma kurucusu `noexcept` **değilse** kopyalamayı zorunlu
kılıyor — yeniden ayırma sırasında bir taşımanın ortasında fırlayan istisna elemanları
kurtarılamaz bırakabilirdi. İki sınıf, biri `noexcept` taşıma kurucusuyla biri onsuz,
`emplace_back` ile büyüdüğünde gerçekten farklı davranıyor mu?

```cpp
// istisna_noexcept_vector_secimi.cpp — noexcept isaretli tasima kurucusu vector yeniden ayirmasinda kopyanin onune geciyor
#include <iostream>
#include <vector>

class GuvenliTasima {
public:
    GuvenliTasima() = default;
    GuvenliTasima(const GuvenliTasima&) { ++kopya_sayaci; }
    GuvenliTasima(GuvenliTasima&&) noexcept { ++tasima_sayaci; }
    static int kopya_sayaci;
    static int tasima_sayaci;
};
int GuvenliTasima::kopya_sayaci = 0;
int GuvenliTasima::tasima_sayaci = 0;

class GuvensizTasima {
public:
    GuvensizTasima() = default;
    GuvensizTasima(const GuvensizTasima&) { ++kopya_sayaci; }
    GuvensizTasima(GuvensizTasima&&) { ++tasima_sayaci; } // noexcept degil
    static int kopya_sayaci;
    static int tasima_sayaci;
};
int GuvensizTasima::kopya_sayaci = 0;
int GuvensizTasima::tasima_sayaci = 0;

int main() {
    {
        std::vector<GuvenliTasima> v;
        v.reserve(1);
        for (int i = 0; i < 5; ++i) {
            v.emplace_back();
        }
    }
    std::cout << std::boolalpha
              << "noexcept tasima kurucusunda yeniden ayirma hic kopya kullandi mi: "
              << (GuvenliTasima::kopya_sayaci > 0) << "\n";
    std::cout << "noexcept tasima kurucusunda yeniden ayirma tasima kullandi mi: "
              << (GuvenliTasima::tasima_sayaci > 0) << "\n";

    {
        std::vector<GuvensizTasima> v;
        v.reserve(1);
        for (int i = 0; i < 5; ++i) {
            v.emplace_back();
        }
    }
    std::cout << "noexcept olmayan tasima kurucusunda yeniden ayirma hic kopya kullandi mi: "
              << (GuvensizTasima::kopya_sayaci > 0) << "\n";

    return 0;
}
```

```
noexcept tasima kurucusunda yeniden ayirma hic kopya kullandi mi: false
noexcept tasima kurucusunda yeniden ayirma tasima kullandi mi: true
noexcept olmayan tasima kurucusunda yeniden ayirma hic kopya kullandi mi: true
```

**CB40.** `GuvenliTasima`'nın taşıma kurucusu `noexcept`: `vector` yeniden ayırırken
kopyayı hiç kullanmıyor — `kopya_sayaci > 0` **false**, `tasima_sayaci > 0` **true**.
`GuvensizTasima`'nınki `noexcept` değil: `vector` kopyalamayı seçiyor —
`kopya_sayaci > 0` **true**. `noexcept` yalnız bir belge notu değil, standart
kütüphane bu sözleşmeye göre **farklı kod** çalıştırıyor; sözü tutmayıp fırlaması
`std::terminate`'i tetikler, o yol burada çalıştırılmadı. Sınıf **kopya**:
`noexcept`'in varlığı, elemanların kopya mı taşıma mı ile taşınacağını belirliyor.

## Sınırlayıcı Ölçüm

Bu derste istisnalar hep tek ya da sıralı birkaç `catch` bloğuyla yakalandı;
`catch (...)` ile her tipin yakalanması ve aynı hiyerarşide **kısmi** eşleşme
kapsam dışı kaldı. `noexcept` işaretli bir işlevden gerçekten fırlatmanın
`std::terminate`'i tetiklemesi ölçülmedi — program temiz bir çıkışla sonlanamayacağı
için sandbox'ta gösterilemiyor; yalnız sözleşmenin tutulduğu durum ölçüldü.
Kopya-değiştir-tokuş kalıbının asıl güvencesi — kopya kurucusunun **kendisi**
fırlarsa `*this`'in dokunulmamış kalması — burada yalnız dolaylı olarak ele alındı,
kopya kurucusunun gerçekten fırlattığı durum ayrıca çalıştırılmadı.

## Özet

- `throw h;` isimli bir yerel değişkeni istisna depolamasına bir kez kopyalıyor;
  `catch (HataNesnesi h)` bu depolanmış nesneyi değerle yakalayarak ikinci bir kopya
  daha çıkarıyor.
- `catch (const HataNesnesi&)` depolanmış nesneye doğrudan bağlanıyor, ek bir kopya
  çıkarmıyor.
- Bir kurucunun gövdesinde fırlatılan istisna, o ana kadar kurulmuş üyeleri kuruluş
  sırasının tersiyle yıkıyor, ama nesnenin kendi yıkıcısını hiç çağırmıyor — kurucu
  tamamlanmadığı için.
- Doğrudan bir geçici nesne fırlatmak (`throw HataNesnesi();`), isimli bir yerel
  fırlatmaktan bir kopya eksik üretiyor.
- Bu dersin ölçtüğü ifade **kopya** sınıfında: bir istisnanın fırlatılma ve yakalanma biçimi,
  sonunda kaç kopyanın çıkarıldığını doğrudan belirliyor.

## Sonraki Adım

Bu derste `HataNesnesi::kopya_sayaci`, `static` bir üye olarak her çağrıda aynı
sayacı paylaştı. Bir sonraki ders, Ad Alanları ve Kod Düzeni, aynı ada sahip iki
sembolün ad alanlarıyla nasıl ayrıştırıldığını ve `static`/`extern` bağlantısının bir
sembolü tek dosyaya mı hapsettiğini yoksa dosyalar arasında mı paylaştırdığını
ölçüyor — yine bir ifadenin hangi sembolle çalıştığı sorusu, ama artık sınıf değil
dosya sınırları üzerinden.
