<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-09T10:13:21+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">C++ Constructor ve Destructor: Nesnelerin Yaşam Döngüsünü Yönetmek</title><link href="https://sonsuzus.github.io/posts/c-constructor-ve-destructor-nesnelerin-yasam-dongusunu-yonetmek/" rel="alternate" type="text/html" title="C++ Constructor ve Destructor: Nesnelerin Yaşam Döngüsünü Yönetmek" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-constructor-ve-destructor-nesnelerin-yasam-dongusunu-yonetmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-constructor-ve-destructor-nesnelerin-yasam-dongusunu-yonetmek/"><![CDATA[<p>C++’ta bir nesne yalnızca değişken tanımlandığında ortaya çıkan basit bir veri paketi değildir; doğar, kullanılır ve zamanı gelince yok olur. Bu yaşam döngüsünün iki başrol oyuncusu <strong>yapıcı metotlar</strong> (constructor) ile <strong>yıkıcı metotlardır</strong> (destructor). Constructor, nesne bellekte oluşturulurken başlangıç durumunu güvenle kurar; destructor ise nesne kapsam dışına çıkarken sahne arkasında kalan kaynakları toplar. Özellikle dosya, ağ bağlantısı, dinamik bellek ve kilit gibi kaynaklarda bu otomasyon, C++’ın en güçlü fikirlerinden biri olan RAII yaklaşımının temelidir.
``</p>

<p>Bir sınıftan nesne üretildiğinde, o nesnenin üyeleri için bellekte yer ayrılır ve ardından constructor çalışır. Constructor’ın adı sınıf adıyla aynıdır, dönüş tipi yoktur ve parametre alabilir. Amaç, nesneyi geçerli bir durumda başlatmaktır. Örneğin bir banka hesabının bakiyesi rastgele bir değerle değil, açıkça belirlenmiş bir başlangıç değeriyle yaşama başlamalıdır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">BankaHesabi</span> <span class="p">{</span>
<span class="nl">private:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">sahip</span><span class="p">;</span>
    <span class="kt">double</span> <span class="n">bakiye</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">BankaHesabi</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">isim</span><span class="p">,</span> <span class="kt">double</span> <span class="n">ilkBakiye</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">sahip</span><span class="p">(</span><span class="n">isim</span><span class="p">),</span> <span class="n">bakiye</span><span class="p">(</span><span class="n">ilkBakiye</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">sahip</span> <span class="o">&lt;&lt;</span> <span class="s">" için hesap açıldı.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">void</span> <span class="nf">paraYatir</span><span class="p">(</span><span class="kt">double</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">miktar</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="n">bakiye</span> <span class="o">+=</span> <span class="n">miktar</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="o">~</span><span class="n">BankaHesabi</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">sahip</span> <span class="o">&lt;&lt;</span> <span class="s">" nesnesi kapatılıyor.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">: sahip(isim), bakiye(ilkBakiye)</code> bölümü <strong>üye başlatma listesi</strong>dir. Atama işleminden daha doğrudan ve çoğu durumda daha verimlidir. Ayrıca <code class="language-plaintext highlighter-rouge">const</code> üyeler ve referans üyeler için tercih değil, zorunluluktur. Constructor çalıştıktan sonra nesnenin temel koşulu, yani <strong>sınıf değişmezi</strong> korunmuş olur. Örneğin bakiyenin negatif olmaması isteniyorsa bu kural daha ilk anda denetlenmelidir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Constructor</th>
      <th>Destructor</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çalışma zamanı</td>
      <td>Nesne oluşturulurken</td>
      <td>Nesne yok edilirken</td>
    </tr>
    <tr>
      <td>Adlandırma</td>
      <td>Sınıf adıyla aynı</td>
      <td>Sınıf adı + <code class="language-plaintext highlighter-rouge">~</code> işareti</td>
    </tr>
    <tr>
      <td>Parametre</td>
      <td>Alabilir, aşırı yüklenebilir</td>
      <td>Parametre almaz, tek tanedir</td>
    </tr>
    <tr>
      <td>Temel görev</td>
      <td>Geçerli başlangıç durumu kurmak</td>
      <td>Kaynakları serbest bırakmak</td>
    </tr>
    <tr>
      <td>Çağrılma biçimi</td>
      <td>Genellikle otomatik</td>
      <td>Genellikle otomatik</td>
    </tr>
  </tbody>
</table>

<p>Destructor’ın önemi, nesnenin sahip olduğu kaynağın türü arttıkça büyür. Sadece <code class="language-plaintext highlighter-rouge">int</code> gibi basit üyeler için özel destructor yazmak gerekmez; derleyici zaten yeterli temizliği üretir. Ancak sınıf <code class="language-plaintext highlighter-rouge">new</code> ile bellek ayırıyor, dosya açıyor veya bir sistem kaynağını kilitliyorsa, bu kaynak mutlaka bırakılmalıdır. Kapsamdan çıkış normal bir <code class="language-plaintext highlighter-rouge">return</code> ile de olsa, hata nedeniyle exception fırlatılmasıyla da olsa destructor çağrılır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;fstream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">GunlukDosyasi</span> <span class="p">{</span>
<span class="nl">private:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="n">dosya</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="k">explicit</span> <span class="n">GunlukDosyasi</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">yol</span><span class="p">)</span> <span class="o">:</span> <span class="n">dosya</span><span class="p">(</span><span class="n">yol</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">dosya</span><span class="p">)</span> <span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="s">"Dosya açılamadı"</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="kt">void</span> <span class="nf">yaz</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">mesaj</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">dosya</span> <span class="o">&lt;&lt;</span> <span class="n">mesaj</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="o">~</span><span class="n">GunlukDosyasi</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// ofstream zaten kapanır; flush çağrısı niyeti görünür kılar.</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">dosya</span><span class="p">.</span><span class="n">is_open</span><span class="p">())</span> <span class="n">dosya</span><span class="p">.</span><span class="n">flush</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu desenin teorik adı <strong>RAII</strong>‘dır: <em>Resource Acquisition Is Initialization</em>. Kaynağın edinilmesi constructor’a, bırakılması destructor’a bağlanır. Böylece kaynak ömrü nesne ömrüne eşitlenir. Bir nesnenin yaşadığı süreyi kabaca $t_{yaşam} = t_{yıkım} - t_{oluşum}$ ile ifade edersek, RAII’da kaynak için de $t_{kaynak} = t_{yaşam}$ hedeflenir. Manuel <code class="language-plaintext highlighter-rouge">delete</code> veya <code class="language-plaintext highlighter-rouge">close</code> çağrısını unutma riski ciddi biçimde azalır.</p>

<p>Dinamik bellek gerekiyorsa ham işaretçiler yerine <code class="language-plaintext highlighter-rouge">std::unique_ptr</code> ve <code class="language-plaintext highlighter-rouge">std::vector</code> gibi RAII uyumlu standart araçları tercih edin. Böylece çoğu zaman destructor yazmanız bile gerekmez: buna <strong>Rule of Zero</strong> denir. Kalıtım kullanılan sınıflarda ise taban sınıf işaretçisi üzerinden silme ihtimali varsa destructor <code class="language-plaintext highlighter-rouge">virtual</code> olmalıdır. Kısacası iyi bir constructor nesneyi güvenilir biçimde başlatır; iyi tasarlanmış bir destructor da ayrılırken arkasında bellek sızıntısı ve açık kaynak bırakmaz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="OOP" /><category term="Constructor" /><category term="Destructor" /><category term="Bellek Yönetimi" /><summary type="html"><![CDATA[C++’ta bir nesne yalnızca değişken tanımlandığında ortaya çıkan basit bir veri paketi değildir; doğar, kullanılır ve zamanı gelince yok olur. Bu yaşam döngüsünün iki başrol oyuncusu yapıcı metotlar (constructor) ile yıkıcı metotlardır (destructor). Constructor, nesne bellekte oluşturulurken başlangıç durumunu güvenle kurar; destructor ise nesne kapsam dışına çıkarken sahne arkasında kalan kaynakları toplar. Özellikle dosya, ağ bağlantısı, dinamik bellek ve kilit gibi kaynaklarda bu otomasyon, C++’ın en güçlü fikirlerinden biri olan RAII yaklaşımının temelidir.]]></summary></entry><entry><title type="html">C ile Basit Bir Mark-and-Sweep Garbage Collector Yazalım</title><link href="https://sonsuzus.github.io/posts/c-ile-basit-bir-mark-and-sweep-garbage-collector-yazalim/" rel="alternate" type="text/html" title="C ile Basit Bir Mark-and-Sweep Garbage Collector Yazalım" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-ile-basit-bir-mark-and-sweep-garbage-collector-yazalim</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-ile-basit-bir-mark-and-sweep-garbage-collector-yazalim/"><![CDATA[<p>Bellek yönetimi, programlamanın “ışıkları kapattım mı?” sorusudur: Bir nesneyi ayırdığımızı hatırlarız ama serbest bırakıp bırakmadığımızdan asla tam emin olamayız. Bu projede C ile küçük bir <strong>mark-and-sweep garbage collector</strong> geliştirerek manuel bellek yönetimini, nesne erişilebilirliğini ve sanal belleğin süreçteki rolünü birlikte inceleyeceğiz.</p>

<p>``</p>

<h2 id="önce-bellek-haritasını-anlayalım">Önce bellek haritasını anlayalım</h2>

<p>Bir süreç çalıştırıldığında işletim sistemi ona geniş ve kesintisiz görünen bir <strong>sanal adres alanı</strong> sunar. Programın kullandığı adresler doğrudan fiziksel RAM adresleri değildir. Sayfa tabloları, sanal sayfaları fiziksel çerçevelere eşler.</p>

<p>Bir adres alanı kabaca kod, global veriler, stack ve heap bölgelerinden oluşur. <code class="language-plaintext highlighter-rouge">malloc</code> ile istediğimiz alan heap üzerinde yönetilir; ancak her <code class="language-plaintext highlighter-rouge">malloc</code> çağrısının anında yeni bir fiziksel sayfa ayırması gerekmez. İşletim sistemi sayfaları ihtiyaç anında eşleyebilir.</p>

<p>Bellek kullanımını basitleştirerek şöyle ifade edebiliriz:</p>

\[M_{etkin} = M_{ayrılan} - M_{erişilemeyen}\]

<p>Garbage collector’ın amacı, artık kök nesnelerden erişilemeyen $M_{erişilemeyen}$ bölümünü bulup yeniden kullanılabilir hâle getirmektir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Manuel yönetim</th>
      <th>Garbage collector</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ayırma</td>
      <td><code class="language-plaintext highlighter-rouge">malloc</code></td>
      <td>GC tarafından izlenen ayırma</td>
    </tr>
    <tr>
      <td>Serbest bırakma</td>
      <td><code class="language-plaintext highlighter-rouge">free</code> çağrısı</td>
      <td>Erişilebilirlik analizinden sonra</td>
    </tr>
    <tr>
      <td>Temel risk</td>
      <td>Sızıntı, çift <code class="language-plaintext highlighter-rouge">free</code></td>
      <td>Duraklama, ek metadata</td>
    </tr>
    <tr>
      <td>Kontrol</td>
      <td>Programcıda</td>
      <td>Çalışma zamanı sisteminde</td>
    </tr>
    <tr>
      <td>Sanal bellek ilişkisi</td>
      <td>Heap sayfalarını kullanır</td>
      <td>Aynı heap içinde canlı nesneleri belirler</td>
    </tr>
  </tbody>
</table>

<h2 id="mark-and-sweep-nasıl-çalışır">Mark-and-sweep nasıl çalışır?</h2>

<p>Algoritma iki temel aşamadan oluşur:</p>

<ol>
  <li><strong>Mark:</strong> Stack, global değişkenler veya çalışma zamanı tarafından tutulan köklerden başlanır. Ulaşılabilen bütün nesneler işaretlenir.</li>
  <li><strong>Sweep:</strong> Ayrılmış nesneler taranır. İşaretlenmemiş olanlar erişilemez kabul edilerek serbest bırakılır.</li>
</ol>

<p>Bu örnekte gerçek stack taraması yapmayacağız. Bunun yerine kökleri açıkça kaydedeceğiz. Böylece algoritmanın özü, platforma özgü ayrıntılar arasında kaybolmayacak.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">Object</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">marked</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">value</span><span class="p">;</span>
    <span class="k">struct</span> <span class="n">Object</span> <span class="o">*</span><span class="n">ref</span><span class="p">;</span>
    <span class="k">struct</span> <span class="n">Object</span> <span class="o">*</span><span class="n">next</span><span class="p">;</span>
<span class="p">}</span> <span class="n">Object</span><span class="p">;</span>

<span class="k">static</span> <span class="n">Object</span> <span class="o">*</span><span class="n">heap</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

<span class="n">Object</span> <span class="o">*</span><span class="nf">gc_alloc</span><span class="p">(</span><span class="kt">int</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">Object</span> <span class="o">*</span><span class="n">obj</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">Object</span><span class="p">));</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">perror</span><span class="p">(</span><span class="s">"malloc"</span><span class="p">);</span>
        <span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">obj</span><span class="o">-&gt;</span><span class="n">marked</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="n">obj</span><span class="o">-&gt;</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
    <span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
    <span class="n">obj</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">heap</span><span class="p">;</span>
    <span class="n">heap</span> <span class="o">=</span> <span class="n">obj</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">obj</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">mark</span><span class="p">(</span><span class="n">Object</span> <span class="o">*</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">marked</span><span class="p">)</span>
        <span class="k">return</span><span class="p">;</span>

    <span class="n">obj</span><span class="o">-&gt;</span><span class="n">marked</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="n">mark</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">ref</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">sweep</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">Object</span> <span class="o">**</span><span class="n">cursor</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">heap</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="o">*</span><span class="n">cursor</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">Object</span> <span class="o">*</span><span class="n">obj</span> <span class="o">=</span> <span class="o">*</span><span class="n">cursor</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">marked</span><span class="p">)</span> <span class="p">{</span>
            <span class="o">*</span><span class="n">cursor</span> <span class="o">=</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
            <span class="n">printf</span><span class="p">(</span><span class="s">"Silindi: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">obj</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">);</span>
            <span class="n">free</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">obj</span><span class="o">-&gt;</span><span class="n">marked</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="n">cursor</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">collect</span><span class="p">(</span><span class="n">Object</span> <span class="o">**</span><span class="n">roots</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">count</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
        <span class="n">mark</span><span class="p">(</span><span class="n">roots</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
    <span class="n">sweep</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">heap</code> listesi ayrılan tüm nesnelerin envanteridir. <code class="language-plaintext highlighter-rouge">ref</code>, bir nesneden diğerine referans oluşturarak küçük bir nesne grafiği kurar. <code class="language-plaintext highlighter-rouge">mark</code> fonksiyonu bu grafiği derinlik öncelikli dolaşır. Döngüsel referanslarda sonsuz özyinelemeyi <code class="language-plaintext highlighter-rouge">marked</code> kontrolü engeller.</p>

<h2 id="collectorı-deneyelim">Collector’ı deneyelim</h2>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">Object</span> <span class="o">*</span><span class="n">a</span> <span class="o">=</span> <span class="n">gc_alloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
    <span class="n">Object</span> <span class="o">*</span><span class="n">b</span> <span class="o">=</span> <span class="n">gc_alloc</span><span class="p">(</span><span class="mi">20</span><span class="p">);</span>
    <span class="n">Object</span> <span class="o">*</span><span class="n">orphan</span> <span class="o">=</span> <span class="n">gc_alloc</span><span class="p">(</span><span class="mi">99</span><span class="p">);</span>

    <span class="n">a</span><span class="o">-&gt;</span><span class="n">ref</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>

    <span class="n">Object</span> <span class="o">*</span><span class="n">roots</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">a</span> <span class="p">};</span>
    <span class="n">collect</span><span class="p">(</span><span class="n">roots</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>

    <span class="n">roots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
    <span class="n">collect</span><span class="p">(</span><span class="n">roots</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İlk koleksiyonda <code class="language-plaintext highlighter-rouge">a</code> köktür; <code class="language-plaintext highlighter-rouge">b</code> nesnesine <code class="language-plaintext highlighter-rouge">a-&gt;ref</code> üzerinden ulaşılır. <code class="language-plaintext highlighter-rouge">orphan</code> ise hiçbir kökten erişilemediği için silinir. İkinci koleksiyonda kök kaldırıldığından hem <code class="language-plaintext highlighter-rouge">a</code> hem <code class="language-plaintext highlighter-rouge">b</code> temizlenir. Referans döngüsü kurulsa bile kökten ulaşılamayan nesneler toplanabilir; bu, referans sayımına göre önemli bir avantajdır.</p>

<h2 id="gerçek-sistemlerden-farkı">Gerçek sistemlerden farkı</h2>

<p>Bu oyuncak collector thread güvenliği, bellek sıkıştırma, nesil tabanlı toplama ve stack taraması sunmaz. Ayrıca özyinelemeli <code class="language-plaintext highlighter-rouge">mark</code>, çok derin grafiklerde stack taşmasına yol açabilir. Üretim sistemleri iş listesinden yararlanan yinelemeli tarama, tri-color marking ve eşzamanlı toplama gibi yöntemler kullanır.</p>

<p>Yine de proje kritik fikri gösterir: <code class="language-plaintext highlighter-rouge">free</code> işlemini otomatikleştirmek yalnızca adresleri takip etmek değildir; programın canlı nesne grafiğini anlamaktır. Sanal bellek bize adres alanını sağlar, allocator blokları dağıtır, garbage collector ise bu bloklardan hangilerinin artık hikâyede rolü kalmadığına karar verir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="C" /><category term="Bellek Yönetimi" /><category term="Garbage Collector" /><summary type="html"><![CDATA[Bellek yönetimi, programlamanın “ışıkları kapattım mı?” sorusudur: Bir nesneyi ayırdığımızı hatırlarız ama serbest bırakıp bırakmadığımızdan asla tam emin olamayız. Bu projede C ile küçük bir mark-and-sweep garbage collector geliştirerek manuel bellek yönetimini, nesne erişilebilirliğini ve sanal belleğin süreçteki rolünü birlikte inceleyeceğiz.]]></summary></entry><entry><title type="html">C++ Kalıtım ile Kod Yeniden Kullanımı: Nesne Hiyerarşileri Kurmak</title><link href="https://sonsuzus.github.io/posts/c-kalitim-ile-kod-yeniden-kullanimi-nesne-hiyerarsileri-kurmak/" rel="alternate" type="text/html" title="C++ Kalıtım ile Kod Yeniden Kullanımı: Nesne Hiyerarşileri Kurmak" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-kalitim-ile-kod-yeniden-kullanimi-nesne-hiyerarsileri-kurmak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-kalitim-ile-kod-yeniden-kullanimi-nesne-hiyerarsileri-kurmak/"><![CDATA[<p>Büyük bir C++ projesinde her nesneyi sıfırdan tanımlamak, kısa sürede kopyala-yapıştır bataklığına dönüşür. Bir aracın, çalışanın ya da oyun karakterinin ortak özellikleri varken bunları tekrar tekrar yazmak yerine kalıtım (inheritance) kullanırız. Kalıtım, bir temel sınıfın (base class) veri ve davranışlarını türetilmiş sınıflara (derived class) aktaran; böylece hem kod tekrarını azaltan hem de anlamlı nesne hiyerarşileri kuran nesne yönelimli programlama mekanizmasıdır.</p>

<p>``</p>

<p>Kalıtımın ana fikri <strong>“bir türüdür”</strong> (<em>is-a</em>) ilişkisidir. Örneğin bir <code class="language-plaintext highlighter-rouge">Araba</code> bir <code class="language-plaintext highlighter-rouge">Arac</code> türüdür; dolayısıyla aracın marka, hız ve hareket etme gibi genel niteliklerini miras alabilir. Buna karşılık, bir arabanın motoru olması <strong>“sahiptir”</strong> (<em>has-a</em>) ilişkisidir ve genellikle composition ile modellenmelidir. Bu ayrımı doğru yapmak, sürdürülebilir tasarımın ilk savunma hattıdır.</p>

<table>
  <thead>
    <tr>
      <th>İlişki</th>
      <th>Anlamı</th>
      <th>Uygun yaklaşım</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Is-a</td>
      <td>Bir nesne, diğerinin özel türüdür</td>
      <td>Kalıtım</td>
      <td><code class="language-plaintext highlighter-rouge">Araba</code>, <code class="language-plaintext highlighter-rouge">Arac</code>tır</td>
    </tr>
    <tr>
      <td>Has-a</td>
      <td>Bir nesne başka bir nesneyi içerir</td>
      <td>Bileşim</td>
      <td><code class="language-plaintext highlighter-rouge">Araba</code> bir <code class="language-plaintext highlighter-rouge">Motor</code>a sahiptir</td>
    </tr>
    <tr>
      <td>Uses-a</td>
      <td>Geçici kullanım ilişkisi vardır</td>
      <td>Bağımlılık</td>
      <td><code class="language-plaintext highlighter-rouge">Servis</code>, <code class="language-plaintext highlighter-rouge">Arac</code> kullanır</td>
    </tr>
  </tbody>
</table>

<p>C++’ta türetilmiş sınıf, temel sınıfın <code class="language-plaintext highlighter-rouge">public</code> üyelerine doğrudan erişebilir; <code class="language-plaintext highlighter-rouge">private</code> üyeler ise miras alınmış olsalar bile doğrudan erişilemez. Bu kural kapsüllemeyi korur. Temel sınıfın kontrollü erişim için sunduğu <code class="language-plaintext highlighter-rouge">protected</code> alanlar vardır, fakat veri üyelerini çoğunlukla <code class="language-plaintext highlighter-rouge">private</code> tutup metotlarla yönetmek daha güvenlidir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">Arac</span> <span class="p">{</span>
<span class="nl">private:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">marka</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">hiz</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">Arac</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">marka</span><span class="p">)</span> <span class="o">:</span> <span class="n">marka</span><span class="p">(</span><span class="n">marka</span><span class="p">),</span> <span class="n">hiz</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="nf">hizlan</span><span class="p">(</span><span class="kt">int</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">hiz</span> <span class="o">+=</span> <span class="n">miktar</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">void</span> <span class="n">bilgileriYazdir</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">marka</span> <span class="o">&lt;&lt;</span> <span class="s">" - "</span> <span class="o">&lt;&lt;</span> <span class="n">hiz</span> <span class="o">&lt;&lt;</span> <span class="s">" km/s</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">ElektrikliAraba</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Arac</span> <span class="p">{</span>
<span class="nl">private:</span>
    <span class="kt">int</span> <span class="n">bataryaYuzdesi</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">ElektrikliAraba</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">marka</span><span class="p">,</span> <span class="kt">int</span> <span class="n">batarya</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">Arac</span><span class="p">(</span><span class="n">marka</span><span class="p">),</span> <span class="n">bataryaYuzdesi</span><span class="p">(</span><span class="n">batarya</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="n">sarjDurumunuYazdir</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Batarya: %"</span> <span class="o">&lt;&lt;</span> <span class="n">bataryaYuzdesi</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">ElektrikliAraba : public Arac</code> ifadesi, herkese açık kalıtımı anlatır. <code class="language-plaintext highlighter-rouge">ElektrikliAraba</code> nesnesi, <code class="language-plaintext highlighter-rouge">Arac</code>ın açık arayüzünü korur; yani <code class="language-plaintext highlighter-rouge">hizlan()</code> ve <code class="language-plaintext highlighter-rouge">bilgileriYazdir()</code> çağrılabilir. Kurucu listesinde yer alan <code class="language-plaintext highlighter-rouge">Arac(marka)</code> çağrısı da önemlidir: Önce temel sınıf bölümü, ardından türetilmiş sınıf bölümü oluşturulur.</p>

<p>Kalıtımın gerçek gücü, çok biçimlilikle (polymorphism) birleştiğinde görünür. Temel sınıftaki bir metodu <code class="language-plaintext highlighter-rouge">virtual</code> yaparsak, temel sınıf işaretçisi üzerinden doğru türetilmiş sınıf davranışı çalışma zamanında seçilir. Mantıksal olarak bu seçim $O(1)$ düzeyinde bir sanal tablo yönlendirmesiyle gerçekleşir; getirisi ise farklı türleri ortak bir arayüzde işleyebilmektir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Amaç</th>
      <th>Anahtar sözcük</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Metot ezme</td>
      <td>Alt sınıfa özel davranış</td>
      <td><code class="language-plaintext highlighter-rouge">override</code></td>
    </tr>
    <tr>
      <td>Dinamik bağlama</td>
      <td>Çalışma anında doğru metodu seçme</td>
      <td><code class="language-plaintext highlighter-rouge">virtual</code></td>
    </tr>
    <tr>
      <td>Güvenli yıkım</td>
      <td>Taban işaretçisinden silme</td>
      <td><code class="language-plaintext highlighter-rouge">virtual ~Sinif()</code></td>
    </tr>
  </tbody>
</table>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Bildirim</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">gonder</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Genel bildirim</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">virtual</span> <span class="o">~</span><span class="n">Bildirim</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">EpostaBildirimi</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Bildirim</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">gonder</span><span class="p">()</span> <span class="k">const</span> <span class="k">override</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"E-posta gönderildi.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kt">void</span> <span class="nf">bildir</span><span class="p">(</span><span class="k">const</span> <span class="n">Bildirim</span><span class="o">&amp;</span> <span class="n">kanal</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">kanal</span><span class="p">.</span><span class="n">gonder</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">bildir()</code> fonksiyonu hangi bildirim türüyle çalıştığını bilmek zorunda değildir. Bu, açık/kapalı ilkesini destekler: Mevcut kodu değiştirmeden yeni <code class="language-plaintext highlighter-rouge">SMSBildirimi</code> sınıfları ekleyebilirsiniz. Ancak her ortak alan için kalıtım kullanmayın. Derin hiyerarşiler, sıkı bağımlılık ve kırılgan taban sınıf sorunları doğurabilir. Sağlam bir kural şudur: Gerçek bir <em>is-a</em> ilişkisi yoksa bileşimi tercih edin; varsa küçük, anlaşılır ve sanal yıkıcısı olan arayüz tabanlı sınıflar tasarlayın.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="Nesne Yönelimli Programlama" /><category term="Kalıtım" /><summary type="html"><![CDATA[Büyük bir C++ projesinde her nesneyi sıfırdan tanımlamak, kısa sürede kopyala-yapıştır bataklığına dönüşür. Bir aracın, çalışanın ya da oyun karakterinin ortak özellikleri varken bunları tekrar tekrar yazmak yerine kalıtım (inheritance) kullanırız. Kalıtım, bir temel sınıfın (base class) veri ve davranışlarını türetilmiş sınıflara (derived class) aktaran; böylece hem kod tekrarını azaltan hem de anlamlı nesne hiyerarşileri kuran nesne yönelimli programlama mekanizmasıdır.]]></summary></entry><entry><title type="html">C++ Referanslar: İşaretçi Karmaşasına Okunaklı Bir Alternatif</title><link href="https://sonsuzus.github.io/posts/c-referanslar-isaretci-karmasasina-okunakli-bir-alternatif/" rel="alternate" type="text/html" title="C++ Referanslar: İşaretçi Karmaşasına Okunaklı Bir Alternatif" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-referanslar-isaretci-karmasasina-okunakli-bir-alternatif</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-referanslar-isaretci-karmasasina-okunakli-bir-alternatif/"><![CDATA[<p>C++’ta referanslar (references), bir değişkene ikinci bir ad vermenin güvenli ve okunaklı yoludur. C’den gelen işaretçiler güçlüdür; ancak <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">&amp;</code>, <code class="language-plaintext highlighter-rouge">-&gt;</code> ve <code class="language-plaintext highlighter-rouge">nullptr</code> kontrolleri özellikle fonksiyon imzalarını hızla zorlaştırabilir. Referans, adres fikrini tamamen gizlemez ama günlük kodda onu daha doğal bir sözdizimiyle sunar: Nesneyle uğraşıyor gibi yazarsınız, derleyici arka planda aynı belleğe erişimi sağlar.
``
Bir referans <code class="language-plaintext highlighter-rouge">&amp;</code> işaretiyle tanımlanır ve <strong>tanımlandığı anda</strong> geçerli bir nesneye bağlanmalıdır. Örneğin <code class="language-plaintext highlighter-rouge">int&amp; takmaAd = puan;</code> satırında yeni bir <code class="language-plaintext highlighter-rouge">int</code> oluşmaz. <code class="language-plaintext highlighter-rouge">takmaAd</code> ve <code class="language-plaintext highlighter-rouge">puan</code>, aynı bellek konumunun iki ismidir. Bu nedenle birini değiştirmek diğerini de değiştirir. Matematiksel olarak, <code class="language-plaintext highlighter-rouge">r</code> referansı <code class="language-plaintext highlighter-rouge">x</code> nesnesine bağlanmışsa, erişim açısından şu ilişki geçerlidir:</p>

\[\operatorname{addr}(r) = \operatorname{addr}(x)\]

<p>Bu ifade referansın ayrı bir değer kopyası olmadığını anlatır. Yine de C++ standardı, referansların bellekte nasıl tutulacağını uygulamaya bırakır; çoğu mimaride derleyici bunu işaretçi benzeri bir mekanizmayla uygular.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="kt">void</span> <span class="nf">zamYap</span><span class="p">(</span><span class="kt">int</span><span class="o">&amp;</span> <span class="n">maas</span><span class="p">,</span> <span class="kt">int</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">maas</span> <span class="o">+=</span> <span class="n">miktar</span><span class="p">;</span> <span class="c1">// Çağıranın değişkeni doğrudan güncellenir.</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">maas</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">;</span>
    <span class="kt">int</span><span class="o">&amp;</span> <span class="n">bordroKaydi</span> <span class="o">=</span> <span class="n">maas</span><span class="p">;</span>

    <span class="n">bordroKaydi</span> <span class="o">=</span> <span class="mi">32000</span><span class="p">;</span>
    <span class="n">zamYap</span><span class="p">(</span><span class="n">maas</span><span class="p">,</span> <span class="mi">2500</span><span class="p">);</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maas</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span> <span class="c1">// 34500</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">zamYap</code>, sonucu <code class="language-plaintext highlighter-rouge">return</code> etmek yerine çağıranın verisini değiştirir. Bu yaklaşım büyük nesneleri kopyalamaktan da kaçınabilir. Fakat yan etki içerdiği için fonksiyon adı ve dokümantasyonu niyeti açıkça belirtmelidir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Değerle parametre</th>
      <th>Referansla parametre</th>
      <th>İşaretçiyle parametre</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kopyalama maliyeti</td>
      <td>Genellikle vardır</td>
      <td>Yoktur</td>
      <td>Yoktur</td>
    </tr>
    <tr>
      <td>Çağrı biçimi</td>
      <td><code class="language-plaintext highlighter-rouge">f(x)</code></td>
      <td><code class="language-plaintext highlighter-rouge">f(x)</code></td>
      <td><code class="language-plaintext highlighter-rouge">f(&amp;x)</code></td>
    </tr>
    <tr>
      <td>Boş olabilme</td>
      <td>Hayır</td>
      <td>Normalde hayır</td>
      <td>Evet, <code class="language-plaintext highlighter-rouge">nullptr</code> olabilir</td>
    </tr>
    <tr>
      <td>Yeniden hedefleme</td>
      <td>Uygulanmaz</td>
      <td>Bağlandıktan sonra hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Kullanım amacı</td>
      <td>Bağımsız kopya</td>
      <td>Zorunlu geçerli nesne</td>
      <td>Opsiyonel nesne/adres işlemleri</td>
    </tr>
  </tbody>
</table>

<p>Referansın en yaygın ve en güvenli kullanım biçimi, salt-okunur büyük verileri <code class="language-plaintext highlighter-rouge">const</code> referansla almaktır. Bir <code class="language-plaintext highlighter-rouge">std::string</code>, <code class="language-plaintext highlighter-rouge">std::vector</code> veya kendi sınıfınızı değerle geçirmek maliyetli kopyalar üretebilir. <code class="language-plaintext highlighter-rouge">const T&amp;</code> ise kopyalamaz ve fonksiyonun nesneyi değiştirmeyeceğini derleyici düzeyinde garanti eder.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="kt">void</span> <span class="nf">kullaniciyiSelamla</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">ad</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ad += "!"; // Hata: const referans değiştirilemez.</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Merhaba, "</span> <span class="o">&lt;&lt;</span> <span class="n">ad</span> <span class="o">&lt;&lt;</span> <span class="s">"!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">const</code> referanslar geçici değerlere de bağlanabilir. Örneğin <code class="language-plaintext highlighter-rouge">const std::string&amp; mesaj = "Merhaba";</code> geçerlidir; geçicinin ömrü referansın kapsamına kadar uzatılır. Buna karşılık normal, yani <code class="language-plaintext highlighter-rouge">const</code> olmayan <code class="language-plaintext highlighter-rouge">T&amp;</code>, geçici bir nesneye bağlanamaz. Bu kural, kısa ömürlü bir nesneyi yanlışlıkla değiştirmeye çalışmayı engeller.</p>

<p>Önemli bir ayrım da şudur: Referansı daha sonra başka bir nesneye “yönlendiremezsiniz”. Aşağıdaki atama referansı değil, bağlı olduğu değeri değiştirir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="kt">int</span><span class="o">&amp;</span> <span class="n">r</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="c1">// r hâlâ a'nın takma adı; a artık 20 olur.</span>
</code></pre></div></div>

<p>Referanslar güvenliği artırsa da ömür sorunlarını sihirli biçimde çözmez. Bir fonksiyondan yerel değişkene referans döndürmek tanımsız davranışa yol açar; fonksiyon bitince o değişken yok olur. Ayrıca bir nesne silindikten sonra ona bağlı referansı kullanmak da hatalıdır.</p>

<table>
  <thead>
    <tr>
      <th>Durum</th>
      <th>Tercih</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Nesneyi değiştirmeden verimli okumak</td>
      <td><code class="language-plaintext highlighter-rouge">const T&amp;</code></td>
    </tr>
    <tr>
      <td>Çağıranın nesnesini zorunlu olarak değiştirmek</td>
      <td><code class="language-plaintext highlighter-rouge">T&amp;</code></td>
    </tr>
    <tr>
      <td>Nesne olmayabilirse</td>
      <td><code class="language-plaintext highlighter-rouge">T*</code> veya modern C++’ta <code class="language-plaintext highlighter-rouge">std::optional</code></td>
    </tr>
    <tr>
      <td>Sahiplik devri</td>
      <td><code class="language-plaintext highlighter-rouge">std::unique_ptr&lt;T&gt;</code></td>
    </tr>
  </tbody>
</table>

<p>Kısacası referans, “bu nesne kesinlikle var ve onunla çalışıyorum” demenin C++ dilindeki güçlü ifadesidir. İşaretçileri tamamen gereksiz kılmaz; ancak zorunlu, boş olmayan ve okunaklı bağlantılar için çoğu zaman ilk tercih olmalıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="Referanslar" /><category term="İşaretçiler" /><category term="Bellek Yönetimi" /><summary type="html"><![CDATA[C++’ta referanslar (references), bir değişkene ikinci bir ad vermenin güvenli ve okunaklı yoludur. C’den gelen işaretçiler güçlüdür; ancak *, &amp;, -&gt; ve nullptr kontrolleri özellikle fonksiyon imzalarını hızla zorlaştırabilir. Referans, adres fikrini tamamen gizlemez ama günlük kodda onu daha doğal bir sözdizimiyle sunar: Nesneyle uğraşıyor gibi yazarsınız, derleyici arka planda aynı belleğe erişimi sağlar.]]></summary></entry><entry><title type="html">C++ Şablonları ve Jenerik Programlama: Tek Algoritma, Birçok Tür</title><link href="https://sonsuzus.github.io/posts/c-sablonlari-ve-jenerik-programlama-tek-algoritma-bircok-tur/" rel="alternate" type="text/html" title="C++ Şablonları ve Jenerik Programlama: Tek Algoritma, Birçok Tür" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-sablonlari-ve-jenerik-programlama-tek-algoritma-bircok-tur</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-sablonlari-ve-jenerik-programlama-tek-algoritma-bircok-tur/"><![CDATA[<p>C++’ta aynı algoritmayı <code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">double</code>, <code class="language-plaintext highlighter-rouge">std::string</code> ya da kendi sınıflarımız için tekrar tekrar yazmak, kodun bakım maliyetini hızla artırır. Şablonlar (templates), algoritmayı türden ayırarak bu sorunu çözer: Bir kez kuralları tanımlar, tür seçimini derleyiciye bırakırsınız. Sonuç, çalışma anında tür kontrolü yapan yapılardan farklı olarak, derleme anında üretilen hızlı ve tür güvenli koddur.
``</p>

<p>Jenerik programlamanın temel fikri şudur: Algoritma, belirli bir sınıf adına değil, ihtiyaç duyduğu <strong>davranışlara</strong> bağımlı olmalıdır. Örneğin bir sıralama algoritması, elemanların <code class="language-plaintext highlighter-rouge">int</code> olmasını istemez; yalnızca karşılaştırılabilir olmalarını ister. Bu yaklaşımın basit maliyet modeli şöyle özetlenebilir:</p>

\[T(n) = T_{algoritma}(n) + T_{tür\,işlemleri}\]

<p>Şablon kullanmak algoritmanın asimptotik karmaşıklığını değiştirmez. Örneğin sıralama hâlâ çoğu durumda $O(n \log n)$’dir. Ancak derleyici türü bildiği için çağrıları satır içine alma (inlining) ve özel optimizasyonlar yapabilir.</p>

<h2 id="fonksiyon-şablonu-türü-derleyici-bulsun">Fonksiyon şablonu: Türü derleyici bulsun</h2>

<p>En tanıdık örnek, iki değerden büyüğünü döndüren bir fonksiyon şablonudur:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">maksimum</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">?</span> <span class="n">a</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maksimum</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maksimum</span><span class="p">(</span><span class="mf">3.14</span><span class="p">,</span> <span class="mf">6.28</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">maksimum</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">"Ada"</span><span class="p">},</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">"Zeynep"</span><span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">typename T</code> yerine <code class="language-plaintext highlighter-rouge">class T</code> da yazılabilir; bu bağlamda anlamları aynıdır. Derleyici ilk çağrıda <code class="language-plaintext highlighter-rouge">T = int</code>, ikinci çağrıda <code class="language-plaintext highlighter-rouge">T = double</code> ve son çağrıda <code class="language-plaintext highlighter-rouge">T = std::string</code> olacak şekilde gerekli sürümleri üretir. Fakat burada görünmez bir sözleşme vardır: <code class="language-plaintext highlighter-rouge">T</code> için <code class="language-plaintext highlighter-rouge">&gt;</code> operatörü tanımlı olmalıdır. Jenerik kodun gücü kadar sorumluluğu da bu sözleşmeleri doğru kurmaktır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Tür kontrolü</th>
      <th>Performans maliyeti</th>
      <th>Yeni tür ekleme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Fonksiyon aşırı yükleme</td>
      <td>Derleme anı</td>
      <td>Düşük</td>
      <td>Her tür için kod gerekir</td>
    </tr>
    <tr>
      <td>Sanal fonksiyon/polimorfizm</td>
      <td>Çalışma anı</td>
      <td>Dolaylı çağrı olabilir</td>
      <td>Ortak taban sınıf ister</td>
    </tr>
    <tr>
      <td>Template</td>
      <td>Derleme anı</td>
      <td>Genellikle sıfır ek maliyet</td>
      <td>Uygun işlemleri sağlayan tür yeterlidir</td>
    </tr>
  </tbody>
</table>

<h2 id="sınıf-şablonları-ve-tür-parametreleri">Sınıf şablonları ve tür parametreleri</h2>

<p>Şablonlar yalnızca fonksiyonlar için değildir. Aşağıdaki <code class="language-plaintext highlighter-rouge">Kutu</code>, içinde hangi değer saklanacağını kullanıcıya bırakır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp">
</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">Kutu</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">explicit</span> <span class="n">Kutu</span><span class="p">(</span><span class="n">T</span> <span class="n">deger</span><span class="p">)</span> <span class="o">:</span> <span class="n">deger_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">deger</span><span class="p">))</span> <span class="p">{}</span>

    <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">al</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">deger_</span><span class="p">;</span> <span class="p">}</span>
    <span class="kt">void</span> <span class="nf">ayarla</span><span class="p">(</span><span class="n">T</span> <span class="n">yeniDeger</span><span class="p">)</span> <span class="p">{</span> <span class="n">deger_</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">yeniDeger</span><span class="p">);</span> <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
    <span class="n">T</span> <span class="n">deger_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Kutu&lt;int&gt;</code> ve <code class="language-plaintext highlighter-rouge">Kutu&lt;std::string&gt;</code> birbirinden farklı türlerdir. Bu önemli ayrım, yanlış türde atamaları daha program çalışmadan yakalar. Ayrıca modern C++’ta şablon parametreleri yalnızca tür olmak zorunda değildir: <code class="language-plaintext highlighter-rouge">std::array&lt;int, 10&gt;</code> örneğindeki <code class="language-plaintext highlighter-rouge">10</code>, derleme zamanı değer parametresidir.</p>

<h2 id="kısıtlar-her-t-gerçekten-uygun-mu">Kısıtlar: Her T gerçekten uygun mu?</h2>

<p>Eski C++ tarzında hatalar, şablonun gövdesi örneklendiğinde uzun derleyici mesajlarıyla ortaya çıkabilirdi. C++20 <code class="language-plaintext highlighter-rouge">concept</code> yapısı, beklentiyi açıkça ifade eder:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;concepts&gt;</span><span class="cp">
</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">totally_ordered</span> <span class="n">T</span><span class="p">&gt;</span>
<span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">maksimumGuvenli</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">a</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">std::totally_ordered</code>, türün anlamlı karşılaştırma işlemlerine sahip olmasını ister. Böylece hata mesajı “<code class="language-plaintext highlighter-rouge">&gt;</code> bulunamadı” ayrıntısına boğulmak yerine, fonksiyonun beklediği kavramı anlatır.</p>

<p>Şablonları kullanırken iki dengeyi koruyun: Arayüzü mümkün olduğunca genel tutun, ancak belirsiz davranışa izin verecek kadar da gevşetmeyin. Standart kütüphanedeki <code class="language-plaintext highlighter-rouge">std::vector</code>, <code class="language-plaintext highlighter-rouge">std::sort</code> ve <code class="language-plaintext highlighter-rouge">std::optional</code> bu felsefenin güçlü örnekleridir. İyi tasarlanmış jenerik kod, türleri değil yetenekleri hedefler; C++ derleyicisi de bu soyut fikri somut, hızlı makine koduna dönüştürür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="Templates" /><category term="Jenerik Programlama" /><summary type="html"><![CDATA[C++’ta aynı algoritmayı int, double, std::string ya da kendi sınıflarımız için tekrar tekrar yazmak, kodun bakım maliyetini hızla artırır. Şablonlar (templates), algoritmayı türden ayırarak bu sorunu çözer: Bir kez kuralları tanımlar, tür seçimini derleyiciye bırakırsınız. Sonuç, çalışma anında tür kontrolü yapan yapılardan farklı olarak, derleme anında üretilen hızlı ve tür güvenli koddur.]]></summary></entry><entry><title type="html">C++ Sınıfları ve Kapsülleme: Veriyi Güvenle Paketlemek</title><link href="https://sonsuzus.github.io/posts/c-siniflari-ve-kapsulleme-veriyi-guvenle-paketlemek/" rel="alternate" type="text/html" title="C++ Sınıfları ve Kapsülleme: Veriyi Güvenle Paketlemek" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-siniflari-ve-kapsulleme-veriyi-guvenle-paketlemek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-siniflari-ve-kapsulleme-veriyi-guvenle-paketlemek/"><![CDATA[<p>C dilinde bir program büyüdükçe, birbirleriyle ilişkili verileri ve bu veriler üzerinde çalışan fonksiyonları takip etmek zorlaşabilir. Örneğin bir banka hesabının bakiye, hesap numarası ve para yatırma fonksiyonu farklı yerlerde durabilir. C++ sınıfları ise bu dağınıklığı toplar: Veri ile o veriyi yöneten davranışlar aynı güvenli kutuda yaşar. Bu yaklaşım, nesne yönelimli programlamanın temel taşlarından olan <strong>kapsülleme</strong>dir.</p>

<p>``</p>

<p>C tarafındaki <code class="language-plaintext highlighter-rouge">struct</code>, farklı alanları tek bir çatı altında gruplamak için harikadır; ancak üyeleri varsayılan olarak dışarıya açıktır. Herhangi bir kod parçası bakiyeyi doğrudan değiştirebilir. C++ içindeki <code class="language-plaintext highlighter-rouge">class</code> ise yalnızca veri grubu değil, aynı zamanda davranış tanımıdır. Sınıfın içindeki fonksiyonlara <strong>üye fonksiyon</strong> veya <strong>metot</strong> denir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>C <code class="language-plaintext highlighter-rouge">struct</code> yaklaşımı</th>
      <th>C++ <code class="language-plaintext highlighter-rouge">class</code> yaklaşımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Veri organizasyonu</td>
      <td>Alanlar bir arada tutulur</td>
      <td>Alanlar ve davranışlar bir aradadır</td>
    </tr>
    <tr>
      <td>Varsayılan erişim</td>
      <td>Genellikle açık kullanım</td>
      <td><code class="language-plaintext highlighter-rouge">class</code> için <code class="language-plaintext highlighter-rouge">private</code></td>
    </tr>
    <tr>
      <td>Doğrulama</td>
      <td>Çağıran kodun sorumluluğu</td>
      <td>Metotlar içinde merkezi doğrulama</td>
    </tr>
    <tr>
      <td>Bakım</td>
      <td>Kurallar birçok yere yayılabilir</td>
      <td>Kurallar sınıf içinde toplanır</td>
    </tr>
  </tbody>
</table>

<p>Kapsüllemenin ana fikri şudur: Bir nesnenin iç durumu, her isteyen tarafından rastgele değiştirilememelidir. Matematiksel olarak bir hesabın bakiyesi için şu değişmezi korumak isteyelim:</p>

\[bakiye \geq 0\]

<p>Eğer <code class="language-plaintext highlighter-rouge">bakiye</code> alanı herkese açık olursa, birisi <code class="language-plaintext highlighter-rouge">bakiye = -500;</code> yazabilir. Oysa para çekme işlemini bir metot üzerinden geçirirsek, sınıf bu kuralı her çağrıda denetler. Böylece nesnenin <strong>geçerli durumunu</strong> korumak tek bir noktadan yönetilir.</p>

<p>Aşağıdaki örnek, bir <code class="language-plaintext highlighter-rouge">BankaHesabi</code> sınıfının temel hâlidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">BankaHesabi</span> <span class="p">{</span>
<span class="nl">private:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">hesapSahibi</span><span class="p">;</span>
    <span class="kt">double</span> <span class="n">bakiye</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">BankaHesabi</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">sahip</span><span class="p">,</span> <span class="kt">double</span> <span class="n">ilkBakiye</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">hesapSahibi</span><span class="p">(</span><span class="n">sahip</span><span class="p">),</span> <span class="n">bakiye</span><span class="p">(</span><span class="n">ilkBakiye</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">ilkBakiye</span> <span class="o">:</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="nf">paraYatir</span><span class="p">(</span><span class="kt">double</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">miktar</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">bakiye</span> <span class="o">+=</span> <span class="n">miktar</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kt">bool</span> <span class="nf">paraCek</span><span class="p">(</span><span class="kt">double</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">miktar</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">miktar</span> <span class="o">&lt;=</span> <span class="n">bakiye</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">bakiye</span> <span class="o">-=</span> <span class="n">miktar</span><span class="p">;</span>
            <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">double</span> <span class="n">bakiyeGetir</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">bakiye</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">BankaHesabi</span> <span class="n">hesap</span><span class="p">(</span><span class="s">"Ada"</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
    <span class="n">hesap</span><span class="p">.</span><span class="n">paraYatir</span><span class="p">(</span><span class="mi">250</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">hesap</span><span class="p">.</span><span class="n">paraCek</span><span class="p">(</span><span class="mi">2000</span><span class="p">))</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Yetersiz bakiye!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">hesap</span><span class="p">.</span><span class="n">bakiyeGetir</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">" TL</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">private</code> altındaki <code class="language-plaintext highlighter-rouge">hesapSahibi</code> ve <code class="language-plaintext highlighter-rouge">bakiye</code>, sınıfın dışından erişilemez. Yani <code class="language-plaintext highlighter-rouge">hesap.bakiye = -10;</code> derleme hatası üretir. <code class="language-plaintext highlighter-rouge">public</code> bölümündeki metotlar ise sınıfın kontrollü arayüzüdür. Kullanıcı bakiyeyi okuyabilir veya değiştirmeyi talep edebilir; fakat kuralları sınıf belirler.</p>

<p><code class="language-plaintext highlighter-rouge">const</code> anahtar sözcüğü de küçük ama güçlü bir sözleşmedir. <code class="language-plaintext highlighter-rouge">bakiyeGetir() const</code>, bu metodun nesnenin durumunu değiştirmeyeceğini söyler. Derleyici bu sözü denetler; böylece salt-okunur metotlara yanlışlıkla değişiklik eklemek zorlaşır.</p>

<table>
  <thead>
    <tr>
      <th>Erişim belirleyicisi</th>
      <th>Kim erişebilir?</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">public</code></td>
      <td>Sınıfın dışındaki herkes</td>
      <td>Kullanıcıya sunulan metotlar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">private</code></td>
      <td>Yalnızca sınıfın kendi metotları</td>
      <td>İç veri ve yardımcı ayrıntılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">protected</code></td>
      <td>Sınıf ve türetilmiş sınıflar</td>
      <td>Kalıtım senaryoları</td>
    </tr>
  </tbody>
</table>

<p>İyi tasarlanmış bir sınıf, kullanıcıya “nasıl sakladığımı düşünme, ne yapabildiğimi kullan” der. Bugün bakiye <code class="language-plaintext highlighter-rouge">double</code> ile tutulabilir; yarın hassas para işlemleri için kuruş cinsinden <code class="language-plaintext highlighter-rouge">long long</code> kullanılabilir. Arayüz aynı kaldığı sürece sınıfı kullanan kodların çoğu etkilenmez. İşte kapsülleme, yalnızca erişim engeli değil; değişime dayanıklı, kuralları net ve daha güvenilir yazılım tasarlama sanatıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="Nesne Yönelimli Programlama" /><category term="Sınıflar" /><category term="Kapsülleme" /><summary type="html"><![CDATA[C dilinde bir program büyüdükçe, birbirleriyle ilişkili verileri ve bu veriler üzerinde çalışan fonksiyonları takip etmek zorlaşabilir. Örneğin bir banka hesabının bakiye, hesap numarası ve para yatırma fonksiyonu farklı yerlerde durabilir. C++ sınıfları ise bu dağınıklığı toplar: Veri ile o veriyi yöneten davranışlar aynı güvenli kutuda yaşar. Bu yaklaşım, nesne yönelimli programlamanın temel taşlarından olan kapsüllemedir.]]></summary></entry><entry><title type="html">C++ STL ile Dinamik Veri Yapıları ve Hızlı Algoritmalar</title><link href="https://sonsuzus.github.io/posts/c-stl-ile-dinamik-veri-yapilari-ve-hizli-algoritmalar/" rel="alternate" type="text/html" title="C++ STL ile Dinamik Veri Yapıları ve Hızlı Algoritmalar" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-stl-ile-dinamik-veri-yapilari-ve-hizli-algoritmalar</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-stl-ile-dinamik-veri-yapilari-ve-hizli-algoritmalar/"><![CDATA[<p>C++ Standart Şablon Kütüphanesi, yani STL (Standard Template Library), tekerleği yeniden icat etmek yerine güvenilir parçalarla hızlı yazılım üretmenin yoludur. Dinamik diziler, bağlı listeler, yığınlar ve hazır algoritmalar sayesinde hem kod miktarı azalır hem de yıllardır test edilmiş uygulamalardan yararlanılır. Asıl güç, veri yapısını doğru probleme; algoritmayı da doğru veri düzenine eşleştirmekte yatar.</p>

<!--more-->

<p>STL üç ana fikrin birleşimidir: <strong>container</strong> (veriyi tutar), <strong>iterator</strong> (veri üzerinde dolaşır) ve <strong>algorithm</strong> (veriye işlem uygular). Bu ayrım oldukça değerlidir: <code class="language-plaintext highlighter-rouge">std::sort</code>, hangi sınıftan geldiğini umursamadan rastgele erişim sunan bir aralık üzerinde çalışır. Böylece veri ile işlem birbirine sıkı sıkıya bağlanmaz.</p>

<p>En sık kullanılan container’lar aşağıdaki gibi karşılaştırılabilir:</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Güçlü yanı</th>
      <th>Zayıf yanı</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::vector</code></td>
      <td>Sonda ekleme ve indeksle erişim çok hızlıdır</td>
      <td>Ortaya ekleme/kaldırma maliyetlidir</td>
      <td>Dinamik dizi, sonuç listesi</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::list</code></td>
      <td>Bilinen konuma ekleme ve silme hızlıdır</td>
      <td>İndeksle erişim yoktur; önbellek dostu değildir</td>
      <td>Sık düğüm silinen zincirler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::deque</code></td>
      <td>Başta ve sonda ekleme hızlıdır</td>
      <td>Bellek düzeni <code class="language-plaintext highlighter-rouge">vector</code> kadar sade değildir</td>
      <td>Çift uçlu kuyruk</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::stack</code></td>
      <td>LIFO işlemlerini sadeleştirir</td>
      <td>Sadece üst elemana erişilir</td>
      <td>Geri alma, parantez kontrolü</td>
    </tr>
  </tbody>
</table>

<p>Bir <code class="language-plaintext highlighter-rouge">vector</code> fiziksel olarak çoğunlukla bitişik bellekte yaşar. Bu nedenle <code class="language-plaintext highlighter-rouge">v[i]</code> erişimi $O(1)$ zamanlıdır ve işlemci önbelleğinden iyi yararlanır. Sona ekleme (<code class="language-plaintext highlighter-rouge">push_back</code>) normalde $O(1)$, kapasite dolduğunda ise yeni alan ayırma nedeniyle $O(n)$ maliyetli olabilir. Buna rağmen büyümenin seyrek gerçekleşmesi sebebiyle amortize maliyet şöyledir:</p>

\[T_{amortize}(push\_back)=O(1)\]

<p>Aşağıdaki örnek, sayıları sıralar, tekrarları temizler ve ikili arama yapar. Buradaki kritik nokta, <code class="language-plaintext highlighter-rouge">binary_search</code> fonksiyonunun doğru sonuç vermesi için aralığın önceden sıralı olmasıdır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">puanlar</span><span class="p">{</span><span class="mi">42</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">17</span><span class="p">};</span>

    <span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">puanlar</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    <span class="k">auto</span> <span class="n">yeniSon</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">unique</span><span class="p">(</span><span class="n">puanlar</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    <span class="n">puanlar</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">yeniSon</span><span class="p">,</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

    <span class="kt">int</span> <span class="n">aranan</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">bulundu</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">binary_search</span><span class="p">(</span>
        <span class="n">puanlar</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">puanlar</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">aranan</span><span class="p">);</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">bulundu</span> <span class="o">?</span> <span class="s">"Puan bulundu"</span> <span class="o">:</span> <span class="s">"Puan yok"</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">unique</code> doğrudan eleman silmez; tekrar edenleri sona taşıyıp yeni mantıksal sonu döndürür. Bu yüzden silme işlemi için <code class="language-plaintext highlighter-rouge">erase</code> ile birlikte kullanılır. Bu kalıp, STL öğrenirken önemli olan iterator mantığını da gösterir.</p>

<p>Algoritma seçimi performansı dramatik biçimde değiştirir:</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Yaklaşım</th>
      <th>Zaman karmaşıklığı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sıralama</td>
      <td><code class="language-plaintext highlighter-rouge">std::sort</code></td>
      <td>$O(n \log n)$</td>
    </tr>
    <tr>
      <td>Sıralı dizide arama</td>
      <td><code class="language-plaintext highlighter-rouge">std::binary_search</code></td>
      <td>$O(\log n)$</td>
    </tr>
    <tr>
      <td>Sırasız dizide arama</td>
      <td><code class="language-plaintext highlighter-rouge">std::find</code></td>
      <td>$O(n)$</td>
    </tr>
    <tr>
      <td>Yığının üstüne ekleme/çıkarma</td>
      <td><code class="language-plaintext highlighter-rouge">push</code> / <code class="language-plaintext highlighter-rouge">pop</code></td>
      <td>$O(1)$</td>
    </tr>
  </tbody>
</table>

<p>Örneğin 1 milyon eleman içinde doğrusal arama en kötü durumda yaklaşık $10^6$ karşılaştırma isterken, ikili arama yaklaşık $\log_2(10^6) \approx 20$ adımda sonuca ulaşabilir. Elbette sıralamanın da bir bedeli vardır; veri yalnızca bir kez aranacaksa <code class="language-plaintext highlighter-rouge">sort</code> her zaman kazanç sağlamaz. Çok sayıda sorgu yapılacaksa ise sıralama maliyeti kısa sürede kendini öder.</p>

<p>Pratik kural basittir: İndeksleme ve yoğun dolaşma için önce <code class="language-plaintext highlighter-rouge">vector</code> düşünün; yalnızca gerçekten gerekli olduğunda <code class="language-plaintext highlighter-rouge">list</code> seçin. LIFO davranışı için <code class="language-plaintext highlighter-rouge">stack</code>, iki uçtan işlem için <code class="language-plaintext highlighter-rouge">deque</code> kullanın. Ardından el yazımı döngülere geçmeden <code class="language-plaintext highlighter-rouge">sort</code>, <code class="language-plaintext highlighter-rouge">find</code>, <code class="language-plaintext highlighter-rouge">count</code>, <code class="language-plaintext highlighter-rouge">transform</code> ve <code class="language-plaintext highlighter-rouge">lower_bound</code> gibi algoritmaları inceleyin. STL, yalnızca daha kısa kod değil; karmaşıklığı görünür, niyeti açık ve bakımı kolay C++ kodu demektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="STL" /><category term="Veri Yapıları" /><category term="Algoritmalar" /><category term="Performans" /><summary type="html"><![CDATA[C++ Standart Şablon Kütüphanesi, yani STL (Standard Template Library), tekerleği yeniden icat etmek yerine güvenilir parçalarla hızlı yazılım üretmenin yoludur. Dinamik diziler, bağlı listeler, yığınlar ve hazır algoritmalar sayesinde hem kod miktarı azalır hem de yıllardır test edilmiş uygulamalardan yararlanılır. Asıl güç, veri yapısını doğru probleme; algoritmayı da doğru veri düzenine eşleştirmekte yatar. STL üç ana fikrin birleşimidir: container (veriyi tutar), iterator (veri üzerinde dolaşır) ve algorithm (veriye işlem uygular). Bu ayrım oldukça değerlidir: std::sort, hangi sınıftan geldiğini umursamadan rastgele erişim sunan bir aralık üzerinde çalışır. Böylece veri ile işlem birbirine sıkı sıkıya bağlanmaz. En sık kullanılan container’lar aşağıdaki gibi karşılaştırılabilir: Yapı Güçlü yanı Zayıf yanı Tipik kullanım std::vector Sonda ekleme ve indeksle erişim çok hızlıdır Ortaya ekleme/kaldırma maliyetlidir Dinamik dizi, sonuç listesi std::list Bilinen konuma ekleme ve silme hızlıdır İndeksle erişim yoktur; önbellek dostu değildir Sık düğüm silinen zincirler std::deque Başta ve sonda ekleme hızlıdır Bellek düzeni vector kadar sade değildir Çift uçlu kuyruk std::stack LIFO işlemlerini sadeleştirir Sadece üst elemana erişilir Geri alma, parantez kontrolü Bir vector fiziksel olarak çoğunlukla bitişik bellekte yaşar. Bu nedenle v[i] erişimi $O(1)$ zamanlıdır ve işlemci önbelleğinden iyi yararlanır. Sona ekleme (push_back) normalde $O(1)$, kapasite dolduğunda ise yeni alan ayırma nedeniyle $O(n)$ maliyetli olabilir. Buna rağmen büyümenin seyrek gerçekleşmesi sebebiyle amortize maliyet şöyledir: \[T_{amortize}(push\_back)=O(1)\] Aşağıdaki örnek, sayıları sıralar, tekrarları temizler ve ikili arama yapar. Buradaki kritik nokta, binary_search fonksiyonunun doğru sonuç vermesi için aralığın önceden sıralı olmasıdır.]]></summary></entry><entry><title type="html">C/C++ İçin GCC, Clang ve VS Code Geliştirme Ortamı Kurulumu</title><link href="https://sonsuzus.github.io/posts/cc-icin-gcc-clang-ve-vs-code-gelistirme-ortami-kurulumu/" rel="alternate" type="text/html" title="C/C++ İçin GCC, Clang ve VS Code Geliştirme Ortamı Kurulumu" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cc-icin-gcc-clang-ve-vs-code-gelistirme-ortami-kurulumu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cc-icin-gcc-clang-ve-vs-code-gelistirme-ortami-kurulumu/"><![CDATA[<p>C ve C++, işlemciye ve belleğe yakın çalışabilmeleri sayesinde işletim sistemlerinden oyun motorlarına kadar pek çok alanda karşımıza çıkar. Ancak ilk programı yazmadan önce derleyici, hata ayıklayıcı ve editör üçlüsünü doğru biçimde hazırlamak gerekir. Bu rehberde GCC/Clang altyapısını kuracak, VS Code’u yapılandıracak ve kaynak kodun çalıştırılabilir programa nasıl dönüştüğünü öğreneceğiz.</p>

<p>``</p>

<h2 id="derleme-süreci-nasıl-çalışır">Derleme süreci nasıl çalışır?</h2>

<p>C/C++ kaynak kodu doğrudan işlemci tarafından anlaşılmaz. Yazdığımız <code class="language-plaintext highlighter-rouge">.c</code> veya <code class="language-plaintext highlighter-rouge">.cpp</code> dosyaları birkaç aşamadan geçer:</p>

<ol>
  <li><strong>Ön işleme:</strong> <code class="language-plaintext highlighter-rouge">#include</code> ve <code class="language-plaintext highlighter-rouge">#define</code> ifadeleri işlenir.</li>
  <li><strong>Derleme:</strong> Kod, assembly diline dönüştürülür.</li>
  <li><strong>Assembly:</strong> Makine kodunu içeren nesne dosyası üretilir.</li>
  <li><strong>Bağlama:</strong> Nesne dosyaları ve kütüphaneler tek programda birleştirilir.</li>
</ol>

<p>Basitleştirilmiş dönüşüm şöyledir:</p>

\[KaynakKod \rightarrow NesneDosyasi \rightarrow CalistirilabilirProgram\]

<p>Donanıma yakınlık özellikle veri boyutlarında hissedilir. Örneğin $N$ bitlik işaretsiz bir tamsayı, $0$ ile $2^N-1$ arasındaki değerleri temsil edebilir. Belleğin sınırlı olduğu gömülü sistemlerde seçilen veri türü bu nedenle önemlidir.</p>

<table>
  <thead>
    <tr>
      <th>Araç</th>
      <th>GCC</th>
      <th>Clang</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>C derleyicisi</td>
      <td><code class="language-plaintext highlighter-rouge">gcc</code></td>
      <td><code class="language-plaintext highlighter-rouge">clang</code></td>
    </tr>
    <tr>
      <td>C++ derleyicisi</td>
      <td><code class="language-plaintext highlighter-rouge">g++</code></td>
      <td><code class="language-plaintext highlighter-rouge">clang++</code></td>
    </tr>
    <tr>
      <td>Güçlü tarafı</td>
      <td>Yaygın platform desteği</td>
      <td>Açıklayıcı hata mesajları</td>
    </tr>
    <tr>
      <td>Hata ayıklayıcı</td>
      <td>GDB</td>
      <td>LLDB</td>
    </tr>
    <tr>
      <td>Lisans ailesi</td>
      <td>GNU GPL</td>
      <td>Apache 2.0</td>
    </tr>
  </tbody>
</table>

<h2 id="derleyici-kurulumu">Derleyici kurulumu</h2>

<p>Ubuntu ve Debian tabanlı sistemlerde GCC araç zinciri şu komutla kurulabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update
<span class="nb">sudo </span>apt <span class="nb">install </span>build-essential gdb
</code></pre></div></div>

<p>Clang kullanmak isteyenler ayrıca şunu çalıştırabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>clang lldb
</code></pre></div></div>

<p>macOS üzerinde Terminal’den <code class="language-plaintext highlighter-rouge">xcode-select --install</code> komutu Apple Clang araçlarını kurar. Windows’ta ise <strong>MSYS2</strong> kurulup UCRT64 terminalinde aşağıdaki komut kullanılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb
</code></pre></div></div>

<p>Ardından MSYS2’nin <code class="language-plaintext highlighter-rouge">ucrt64/bin</code> klasörü <code class="language-plaintext highlighter-rouge">PATH</code> değişkenine eklenmelidir. Kurulumu doğrulamak için <code class="language-plaintext highlighter-rouge">gcc --version</code>, <code class="language-plaintext highlighter-rouge">g++ --version</code> veya <code class="language-plaintext highlighter-rouge">clang --version</code> çalıştırılır.</p>

<h2 id="i̇lk-program-ve-manuel-derleme">İlk program ve manuel derleme</h2>

<p><code class="language-plaintext highlighter-rouge">main.cpp</code> adında bir dosya oluşturalım:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">sayi</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Bellekteki değer: "</span> <span class="o">&lt;&lt;</span> <span class="n">sayi</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Programı GCC ile derlemek için şu komut yeterlidir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>g++ <span class="nt">-std</span><span class="o">=</span>c++20 <span class="nt">-Wall</span> <span class="nt">-Wextra</span> <span class="nt">-g</span> main.cpp <span class="nt">-o</span> uygulama
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">-std=c++20</code> dil standardını seçer, <code class="language-plaintext highlighter-rouge">-Wall -Wextra</code> olası hatalar için uyarıları açar, <code class="language-plaintext highlighter-rouge">-g</code> ise hata ayıklama bilgisi ekler. Linux/macOS üzerinde program <code class="language-plaintext highlighter-rouge">./uygulama</code>, Windows’ta <code class="language-plaintext highlighter-rouge">uygulama.exe</code> komutuyla çalıştırılır.</p>

<h2 id="vs-code-yapılandırması">VS Code yapılandırması</h2>

<p>VS Code’a <strong>C/C++</strong> uzantısını kurduktan sonra proje klasöründe <code class="language-plaintext highlighter-rouge">.vscode/tasks.json</code> dosyası oluşturulur:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0.0"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"tasks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"C++ Derle"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"shell"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"g++"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"args"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">"-std=c++20"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"-Wall"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"-Wextra"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"-g"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"${file}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"-o"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"${fileDirname}/${fileBasenameNoExtension}"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"group"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"kind"</span><span class="p">:</span><span class="w"> </span><span class="s2">"build"</span><span class="p">,</span><span class="w"> </span><span class="nl">"isDefault"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">},</span><span class="w">
      </span><span class="nl">"problemMatcher"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"$gcc"</span><span class="p">]</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Bu görev, açık olan dosyayı <strong>Ctrl+Shift+B</strong> ile derler. Clang tercih ediliyorsa <code class="language-plaintext highlighter-rouge">command</code> alanı <code class="language-plaintext highlighter-rouge">clang++</code> yapılabilir.</p>

<p>Hata ayıklama sırasında breakpoint kullanmak, değişkenlerin bellekteki değişimini adım adım izlemeyi sağlar. VS Code’un <strong>Run and Debug</strong> bölümünden C++ yapılandırması seçildiğinde GDB veya LLDB çalıştırılır. Böylece yalnızca programın sonucunu değil; çağrı yığınını, işaretçileri ve bellek adreslerini de inceleyebilirsiniz.</p>

<p>Son olarak derleyici uyarılarını düşman değil, ücretsiz kod inceleme ekibi olarak görün. C/C++ öğrenirken <code class="language-plaintext highlighter-rouge">-Wall -Wextra</code> kullanmak ve küçük programları hata ayıklayıcıyla yürütmek, bellek yönetimi ile donanım arasındaki ilişkiyi çok daha görünür hâle getirir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C/C++" /><category term="VS Code" /><category term="GCC ve Clang" /><summary type="html"><![CDATA[C ve C++, işlemciye ve belleğe yakın çalışabilmeleri sayesinde işletim sistemlerinden oyun motorlarına kadar pek çok alanda karşımıza çıkar. Ancak ilk programı yazmadan önce derleyici, hata ayıklayıcı ve editör üçlüsünü doğru biçimde hazırlamak gerekir. Bu rehberde GCC/Clang altyapısını kuracak, VS Code’u yapılandıracak ve kaynak kodun çalıştırılabilir programa nasıl dönüştüğünü öğreneceğiz.]]></summary></entry><entry><title type="html">C/C++ Ön İşlemci Komutları: Derleyiciden Önce Sahne Alan Makrolar</title><link href="https://sonsuzus.github.io/posts/cc-on-islemci-komutlari-derleyiciden-once-sahne-alan-makrolar/" rel="alternate" type="text/html" title="C/C++ Ön İşlemci Komutları: Derleyiciden Önce Sahne Alan Makrolar" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cc-on-islemci-komutlari-derleyiciden-once-sahne-alan-makrolar</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cc-on-islemci-komutlari-derleyiciden-once-sahne-alan-makrolar/"><![CDATA[<p>C ve C++ kodu, derleyicinin eline doğrudan yazdığımız hâliyle ulaşmaz. Arada metin tabanlı ama etkisi büyük bir aşama vardır: <strong>ön işlemci</strong> (preprocessor). <code class="language-plaintext highlighter-rouge">#include</code>, <code class="language-plaintext highlighter-rouge">#define</code> ve <code class="language-plaintext highlighter-rouge">#ifdef</code> gibi satırlarla çalışan bu mekanizma, kaynak kodu derlenmeden hemen önce dönüştürür. Bunu bir tiyatro oyununun sahne arkası ekibi gibi düşünebilirsiniz: oyuncular (derleyici) sahneye çıkmadan dekorlar yerleşir, bazı replikler değiştirilir ve şartlara uymayan sahneler tamamen kaldırılır.</p>

<p>``</p>

<h2 id="derleme-zincirindeki-yeri">Derleme zincirindeki yeri</h2>

<p>Bir C/C++ programının yolculuğu kabaca dört adımdan oluşur. Ön işlemci ilk adımda kaynak metni düzenler; henüz tür kontrolü yapmaz, fonksiyon çağırmaz ve C++ sözdizimini derinlemesine analiz etmez. Temel olarak karakter dizileri üzerinde çalışır.</p>

\[\text{Kaynak Kod} \xrightarrow{\text{Preprocess}} \text{Genişletilmiş Kod} \xrightarrow{\text{Compile}} \text{Nesne Dosyası} \xrightarrow{\text{Link}} \text{Çalıştırılabilir Dosya}\]

<table>
  <thead>
    <tr>
      <th>Aşama</th>
      <th>Girdi</th>
      <th>Temel görev</th>
      <th>Çıktı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ön işleme</td>
      <td><code class="language-plaintext highlighter-rouge">.c</code>, <code class="language-plaintext highlighter-rouge">.cpp</code>, <code class="language-plaintext highlighter-rouge">.h</code></td>
      <td>Makro açma, dosya ekleme, koşullu kod seçme</td>
      <td>Düzenlenmiş kaynak</td>
    </tr>
    <tr>
      <td>Derleme</td>
      <td>Düzenlenmiş kaynak</td>
      <td>Sözdizimi ve tür kontrolü, makine koduna yakın üretim</td>
      <td><code class="language-plaintext highlighter-rouge">.o</code> / <code class="language-plaintext highlighter-rouge">.obj</code></td>
    </tr>
    <tr>
      <td>Bağlama</td>
      <td>Nesne dosyaları, kütüphaneler</td>
      <td>Sembolleri birleştirme</td>
      <td>Uygulama</td>
    </tr>
  </tbody>
</table>

<p>Örneğin <code class="language-plaintext highlighter-rouge">#include &lt;stdio.h&gt;</code> yazdığınızda ön işlemci, ilgili başlık dosyasının içeriğini mantıksal olarak o satıra ekler. Bu yüzden başlık dosyalarında tekrar eden eklemeleri önlemek kritik önemdedir.</p>

<h2 id="define-metinsel-kısayol-sihirli-değnek-değil"><code class="language-plaintext highlighter-rouge">#define</code>: Metinsel kısayol, sihirli değnek değil</h2>

<p>Nesne benzeri makrolar sabit metinleri değiştirir. Fonksiyon benzeri makrolar ise parametre alabilir:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="cp">#define MAX_KULLANICI 100
#define KARE(x) ((x) * (x))
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">sayi</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Limit: %d, kare: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">MAX_KULLANICI</span><span class="p">,</span> <span class="n">KARE</span><span class="p">(</span><span class="n">sayi</span> <span class="o">+</span> <span class="mi">1</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">KARE(sayi + 1)</code>, <code class="language-plaintext highlighter-rouge">((sayi + 1) * (sayi + 1))</code> biçimine dönüşür. Parantezler hayati ayrıntıdır. <code class="language-plaintext highlighter-rouge">#define KARE(x) x * x</code> olsaydı <code class="language-plaintext highlighter-rouge">KARE(2 + 3)</code> ifadesi <code class="language-plaintext highlighter-rouge">2 + 3 * 2 + 3</code> olur ve beklenen $25$ yerine $11$ üretirdi.</p>

<p>Makroların tür bilgisi yoktur; bu nedenle modern C++ kodunda sabitler için çoğu zaman <code class="language-plaintext highlighter-rouge">constexpr</code>, küçük işlevler için <code class="language-plaintext highlighter-rouge">inline</code> fonksiyonlar daha güvenlidir.</p>

<table>
  <thead>
    <tr>
      <th>İhtiyaç</th>
      <th>Makro</th>
      <th>Daha güvenli alternatif</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Derleme zamanı sabiti</td>
      <td><code class="language-plaintext highlighter-rouge">#define PI 3.14</code></td>
      <td><code class="language-plaintext highlighter-rouge">constexpr double pi = 3.14;</code></td>
    </tr>
    <tr>
      <td>Küçük hesaplama</td>
      <td><code class="language-plaintext highlighter-rouge">#define MIN(a,b)</code></td>
      <td>Şablon veya <code class="language-plaintext highlighter-rouge">inline</code> fonksiyon</td>
    </tr>
    <tr>
      <td>Platform seçimi</td>
      <td><code class="language-plaintext highlighter-rouge">#ifdef _WIN32</code></td>
      <td>Ön işlemci genellikle uygundur</td>
    </tr>
  </tbody>
</table>

<h2 id="koşullu-derleme-kodun-hangi-evrende-yaşayacağını-seçmek">Koşullu derleme: Kodun hangi evrende yaşayacağını seçmek</h2>

<p><code class="language-plaintext highlighter-rouge">#if</code>, <code class="language-plaintext highlighter-rouge">#ifdef</code>, <code class="language-plaintext highlighter-rouge">#ifndef</code>, <code class="language-plaintext highlighter-rouge">#elif</code> ve <code class="language-plaintext highlighter-rouge">#endif</code>, belirli blokların ön işlemci tarafından korunmasını veya silinmesini sağlar. Özellikle hata ayıklama, özellik bayrakları ve işletim sistemi farkları için kullanılır.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="cp">#define DEBUG_MODU
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
<span class="cp">#ifdef DEBUG_MODU
</span>    <span class="n">printf</span><span class="p">(</span><span class="s">"[DEBUG] Program baslatildi.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="cp">#endif
</span>
<span class="cp">#if defined(_WIN32)
</span>    <span class="n">printf</span><span class="p">(</span><span class="s">"Windows platformu</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="cp">#else
</span>    <span class="n">printf</span><span class="p">(</span><span class="s">"Windows disindaki bir platform</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="cp">#endif
</span>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">DEBUG_MODU</code> tanımlı değilse debug satırı derleyiciye hiç ulaşmaz. Bu, <code class="language-plaintext highlighter-rouge">if (false)</code> yazmaktan farklıdır: ikinci durumda kod hâlâ sözdizimsel olarak geçerli olmak zorundadır; koşullu derlemede ise blok kaynak çıktıdan tamamen çıkar.</p>

<p>Başlık dosyalarında klasik koruma deseni de aynı fikri kullanır:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#ifndef HESAPLAYICI_H
#define HESAPLAYICI_H
</span>
<span class="kt">int</span> <span class="nf">topla</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">);</span>

<span class="cp">#endif
</span></code></pre></div></div>

<p>Bu yapı, dosya birden fazla kez eklense bile bildirimin yalnızca bir kez işlenmesini sağlar. Ön işlemci güçlüdür; fakat metinsel çalıştığı için dikkat ister. Makroları küçük, açık isimli ve zorunlu oldukları alanlarla sınırlı tutmak, derleme sahnesinin perde arkasını kontrol altında tutmanın en iyi yoludur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C" /><category term="C++" /><category term="Preprocessor" /><category term="Derleme" /><category term="Makro" /><summary type="html"><![CDATA[C ve C++ kodu, derleyicinin eline doğrudan yazdığımız hâliyle ulaşmaz. Arada metin tabanlı ama etkisi büyük bir aşama vardır: ön işlemci (preprocessor). #include, #define ve #ifdef gibi satırlarla çalışan bu mekanizma, kaynak kodu derlenmeden hemen önce dönüştürür. Bunu bir tiyatro oyununun sahne arkası ekibi gibi düşünebilirsiniz: oyuncular (derleyici) sahneye çıkmadan dekorlar yerleşir, bazı replikler değiştirilir ve şartlara uymayan sahneler tamamen kaldırılır.]]></summary></entry><entry><title type="html">C++’ta Çok Biçimlilik ve Virtual Fonksiyonlar: Geç Bağlamanın Gücü</title><link href="https://sonsuzus.github.io/posts/cta-cok-bicimlilik-ve-virtual-fonksiyonlar-gec-baglamanin-gucu/" rel="alternate" type="text/html" title="C++’ta Çok Biçimlilik ve Virtual Fonksiyonlar: Geç Bağlamanın Gücü" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cta-cok-bicimlilik-ve-virtual-fonksiyonlar-gec-baglamanin-gucu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cta-cok-bicimlilik-ve-virtual-fonksiyonlar-gec-baglamanin-gucu/"><![CDATA[<p>C++ nesne yönelimli programlamanın en etkileyici fikirlerinden biri, aynı arayüzün farklı nesnelerde farklı sonuçlar üretmesidir. Buna <strong>çok biçimlilik</strong> (<em>polymorphism</em>) denir. Bir <code class="language-plaintext highlighter-rouge">Animal*</code> işaretçisiyle hem kediye hem köpeğe ses çıkarttırabilmek, kodun her somut sınıfı tek tek tanımasına gerek kalmadan genişlemesini sağlar. Bu esneklik, özellikle oyun motorları, ödeme sistemleri ve eklenti mimarilerinde hayat kurtarır.</p>

<p>``</p>

<h2 id="bağlama-zamanı-neden-önemlidir">Bağlama zamanı neden önemlidir?</h2>

<p>Bir fonksiyon çağrısının hangi fonksiyona gideceğine karar verilmesine <strong>bağlama</strong> (<em>binding</em>) denir. Normal üye fonksiyonlarda karar derleme zamanında verilir; bu, <strong>erken bağlama</strong>dır. <code class="language-plaintext highlighter-rouge">virtual</code> anahtar sözcüğü ise kararı çalışma zamanına bırakır: <strong>geç bağlama</strong> (<em>late binding</em>).</p>

<p>Teorik olarak, temel sınıf işaretçisinin türü $B$ ve işaret ettiği gerçek nesnenin türü $D$ olsun. Virtual bir çağrının seçimi işaretçinin statik türüne değil, nesnenin dinamik türüne bağlıdır:</p>

\[f(B^*) \rightarrow f(D)\]

<p>Bu küçük görünen fark, kalıtım zincirinin gerçek gücünü açığa çıkarır. Aşağıdaki tabloda iki yaklaşımın özeti bulunuyor:</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Normal fonksiyon</th>
      <th><code class="language-plaintext highlighter-rouge">virtual</code> fonksiyon</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Karar zamanı</td>
      <td>Derleme zamanı</td>
      <td>Çalışma zamanı</td>
    </tr>
    <tr>
      <td>Seçim ölçütü</td>
      <td>İşaretçinin/referansın türü</td>
      <td>Gerçek nesne türü</td>
    </tr>
    <tr>
      <td>Performans</td>
      <td>Çok az daha doğrudan</td>
      <td>Dolaylı çağrı maliyeti olabilir</td>
    </tr>
    <tr>
      <td>Esneklik</td>
      <td>Düşük</td>
      <td>Yüksek</td>
    </tr>
    <tr>
      <td>Kullanım alanı</td>
      <td>Sabit davranış</td>
      <td>Genişletilebilir hiyerarşiler</td>
    </tr>
  </tbody>
</table>

<h2 id="kedi-mi-konuşuyor-hayvan-mı">Kedi mi konuşuyor, hayvan mı?</h2>

<p>Önce temel sınıfın ortak sözleşmeyi tanımladığını düşünelim. <code class="language-plaintext highlighter-rouge">speak()</code> tüm hayvanlar için anlamlıdır, fakat ürettiği ses her hayvanda farklıdır. Saf sanal fonksiyon kullanmak, <code class="language-plaintext highlighter-rouge">Animal</code> sınıfının doğrudan nesne üretmek yerine bir soyutlama olduğunu açıkça söyler.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;memory&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">Animal</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">speak</span><span class="p">()</span> <span class="k">const</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">virtual</span> <span class="o">~</span><span class="n">Animal</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Cat</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Animal</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">speak</span><span class="p">()</span> <span class="k">const</span> <span class="k">override</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Miyav!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Dog</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Animal</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">speak</span><span class="p">()</span> <span class="k">const</span> <span class="k">override</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Hav hav!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Animal</span><span class="o">&gt;&gt;</span> <span class="n">animals</span><span class="p">;</span>
    <span class="n">animals</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">Cat</span><span class="o">&gt;</span><span class="p">());</span>
    <span class="n">animals</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">Dog</span><span class="o">&gt;</span><span class="p">());</span>

    <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">animal</span> <span class="o">:</span> <span class="n">animals</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">animal</span><span class="o">-&gt;</span><span class="n">speak</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">animals</code> vektörü yalnızca <code class="language-plaintext highlighter-rouge">Animal</code> arayüzünü bilir. Buna rağmen ilk çağrı <code class="language-plaintext highlighter-rouge">Cat::speak()</code>, ikinci çağrı <code class="language-plaintext highlighter-rouge">Dog::speak()</code> olur. Derleyici bu davranışı çoğu uygulamada <strong>vtable</strong> adı verilen fonksiyon işaretçisi tablosu üzerinden gerçekleştirir. Standart, vtable’ın tam uygulama ayrıntısını zorunlu kılmaz; ancak zihinsel model olarak oldukça faydalıdır.</p>

<h2 id="override-ve-sanal-yıkıcı-i̇ki-önemli-emniyet-kemeri"><code class="language-plaintext highlighter-rouge">override</code> ve sanal yıkıcı: İki önemli emniyet kemeri</h2>

<p>Türetilmiş sınıfta <code class="language-plaintext highlighter-rouge">override</code> kullanmak zorunlu değildir, ama güçlü biçimde önerilir. Örneğin yanlışlıkla <code class="language-plaintext highlighter-rouge">void speak()</code> yerine <code class="language-plaintext highlighter-rouge">void speak(int)</code> yazarsanız, derleyici bunun üst sınıftaki fonksiyonu ezmediğini hemen bildirir. Böylece sessiz ve pahalı hatalar önlenir.</p>

<p>Bir diğer kritik ayrıntı, temel sınıfın yıkıcısının <code class="language-plaintext highlighter-rouge">virtual</code> olmasıdır. Aksi halde <code class="language-plaintext highlighter-rouge">Animal*</code> üzerinden silinen bir <code class="language-plaintext highlighter-rouge">Cat</code> nesnesinde türetilmiş sınıfın yıkıcısı çalışmayabilir. Kaynak yöneten sınıflarda bu durum bellek sızıntısı veya eksik temizlik demektir.</p>

<table>
  <thead>
    <tr>
      <th>Tercih</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">virtual void speak()</code></td>
      <td>Davranış dinamik türe göre seçilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">void speak()</code></td>
      <td>Temel işaretçi üzerinden temel sürüm çağrılabilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">void speak() override</code></td>
      <td>Ezme niyeti derleyici tarafından doğrulanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">virtual ~Animal()</code></td>
      <td>Temel işaretçiyle güvenli yok etme sağlar</td>
    </tr>
  </tbody>
</table>

<p>Sonuç olarak çok biçimlilik, <code class="language-plaintext highlighter-rouge">if</code> ve <code class="language-plaintext highlighter-rouge">switch</code> zincirleriyle tür kontrolü yapma ihtiyacını azaltır. Sisteme yeni bir <code class="language-plaintext highlighter-rouge">Bird</code> sınıfı eklediğinizde mevcut döngüyü değiştirmek yerine yalnızca <code class="language-plaintext highlighter-rouge">speak()</code> davranışını tanımlarsınız. İşte geç bağlama, C++ kodunu hem daha okunur hem de değişime daha dayanıklı yapan mekanizmadır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="C++" /><category term="Nesne Yönelimli Programlama" /><category term="Polymorphism" /><category term="Virtual Fonksiyonlar" /><summary type="html"><![CDATA[C++ nesne yönelimli programlamanın en etkileyici fikirlerinden biri, aynı arayüzün farklı nesnelerde farklı sonuçlar üretmesidir. Buna çok biçimlilik (polymorphism) denir. Bir Animal* işaretçisiyle hem kediye hem köpeğe ses çıkarttırabilmek, kodun her somut sınıfı tek tek tanımasına gerek kalmadan genişlemesini sağlar. Bu esneklik, özellikle oyun motorları, ödeme sistemleri ve eklenti mimarilerinde hayat kurtarır.]]></summary></entry></feed>