top of page

C++ Dilinde mutable

  • Writer: Yusuf Hançar
    Yusuf Hançar
  • Aug 11, 2023
  • 2 min read

Updated: Sep 8, 2023

C++ dilinde modern c++ ile eklenen mutable specifier const üye fonksiyonların sınıfın(class veya struct) üye elemanlarını değiştirebilmesi için eklenmiştir. Bu specifier kullanılırken tabiki kod maliyeti, performans gibi parametreler dikkate alınacaktır. Sağladığı avantajlar ve diğer tarafta dezavantajlarını da bilirsek daha verimli bir tasarım ortaya koyabiliriz.


class SmartCode { 
private: 
    mutable int m_time{}; 

public: 
    void smart_func()const 
    { 
        m_time = 23;     
        cout << m_age << endl; 
    } 
};

int main() 
{ 
    SmartCode sc; 
    sc.smart_func(); 
}
*****************************
AÇIKLAMA: const üye fonksiyon mutable olan m_time değişkenini içeride kullanabilir ve değiştirebilmektedir.
*****************************
CEVAP: 56
*****************************
class SmartCode { 
private: 
    int m_val{}; 

public: 
    void smart_func()const 
    { 
        m_val = 23;       
        cout << m_val << endl; 
    } 
};

int main() 
{ 
    SmartCode sc; 
    sc.smart_func(); 
}
*****************************
AÇIKLAMA: const üye fonksiyon non-static m_val değişkenini değiştiremez.
*****************************
CEVAP: syntax error
*****************************
int main()  
{  
    int sc = 10;  

    auto val = [sc]() mutable{ ++sc; }; 

    cout << "sc : " << sc << endl;  
} 
*****************************
AÇIKLAMA: mutable olmasaydı syntax hatası olurdu. Capture edilen(yakalanan denilebilir) değişkenler lambda ifadesine dışarıdan erişilebilir hale getirir. Ancak lambda ifadesi içindeki '++sc' işlemi yapıldığında bunun capture([]) kısmı ile başlamış ise capture edilen değişkenler default  'const' olarak ele alınır. Yani değiştirmeye çalışmak hata olacaktır.
Bu örnekte hata olmasa da sc değişkeni yinede artırılmaması val lambda ifadesinin çağırılmaması ve referans olarak capture edilmemesidir. Bu açıklamaya göre düzenleyerek deneyebilirsiniz... 
*****************************
CEVAP: legal
*****************************
Lambda ileriki yazılarda detaylı anlatılacaktır...!

Performans iyileştirmesinin yanısıra bir hesaplamanın sonucunu önbelleğe alma gibi senaryolarda da fayda sağlayabilmektedir. Bir hesaplama sonucu sık sık kullanılıyor ve sık sık değişmiyorsa bu sonucu birkez hesaplayarak önbellekte tutabiliriz. Burada mutable specifier kullanılarak bu hesaplama sonucu 'const' fonksiyonlar içinde de değiştirilebilmektedir.


class SmartCodeCalc {
public:
    int get_result() const 
    {
        if (!m_cache) 
        {
            res = cache_calc();
            m_cache = true;
        }
        
        return res;
    }

private:
    mutable int res{};
    mutable bool m_cache{false};

    int cache_calc() const 
    {
         int ret{};

        for (int idx{}; idx < 1000000; ++idx) 
        {
            ret += idx;
        }

        return ret;
    }
};

int main()
{
}
*****************************
AÇIKLAMA: burada cache_calc fonksiyonu içinde karmaşık bir hesap yapılıyor ve önbellekte tutuluyor.
*****************************
CEVAP: 
*****************************
#include <iostream>
#include <functional>
#include <sys/stat.h>
#include <chrono>

using namespace std;

class FileStat {
public:
    FileStat(string name) : m_name(std::move(name)){}

    bool is_modify() const
    {
        if (!m_modify_check)
        {
            check_modify();
            m_modify_check=true;
        }

        return m_modified;
    }

private:
    const std::string m_name;

    mutable bool m_modify_check{ false };

    mutable bool m_modified{ false };

    void check_modify() const
    {
        auto curr_time = chrono::system_clock::now().time_since_epoch();

        struct stat fileInfo;

        if (0 == stat(m_name.c_str(), &fileInfo))
        {
            auto last_modify = static_cast<long>(fileInfo.st_mtime); 

            if (last_modify > chrono::duration_cast<chrono::seconds>(curr_time).count())
            {
                m_modified = true;
            }
        }
    }
};

int main() 
{
    FileStat file("smartcode.txt");
    
    cout << "is modified : " 
         << (file.is_modify() ? "Yes" : "No") << endl;
    
    return 0;
}
*****************************
AÇIKLAMA: check_modify fonksiyonu içerisinde mutable değişkenler ile bazı işlemler yapılarak önbellek kullanımının ve performans artışının senaryosu çizilmeye çalışılmıştır. Ancak bu işlemleri dikkatli yapmak oldukça önemlidir. m_modify_check flag'i check_modify() fonksiyonunu bir kez çağırarak sonucunu önbellekte tutar ve gereksiz tekrarlı hesaplamaların önüne geçilir. m_modified flag ise file değişim durumunu önbellekte tutarak her defasında dosyanın durumunu kontrol etme işinden kurtarır.
*****************************
CEVAP: is modified : No
*****************************
ree

 
 
 

Recent Posts

See All
C++ Dilinde [[nodiscard]] attribute

C++’ta [[attribute]] (öznitelik) mekanizması, kod hakkında ek bilgi sağlayarak derleyicinin uyarılar vermesine, belirli optimizasyonlar...

 
 
 
C++ Dilinde constinit

C++20'de tanıtılan önemli bir özellik `constinit`'dir; bu özellik, statik depolama süresine sahip değişkenlerin derleme zamanında...

 
 
 

Comments


bottom of page