Şimdi Ara

C++'da Singleton Pattern

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
2 Misafir - 2 Masaüstü
5 sn
5
Cevap
0
Favori
891
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • Arkadaşlar şu anki uğraştığım projede sadece bir defa örneklenmesi gereken sınıflar var.
    Bunu nasıl başarabilirim diye düşünürken singleton pattern olayını hatırladım fakat bir türlü nasıl çalıştığını anlayamadım.
    C++ bilgim yüksek değil, o yüzden bana sade ve anlaşılır bir şekilde anlatabilir ya da uygun bir link verebilir misiniz?

    Teşükkürler .



  • class içine kendi sınıfından static bir referans tanımla. instance olsun adı.

    daha sonra yapılandırıcı metodun iznini korumalı yap. private

    gene static bir motod oluştur getInstance diyebilirsin mesela. geri döndürdüğü sınıf gene kendisi olsun.

    bu metodun içine eğer instance null ise instance a yeni bir kendi classını oluştur.
    en alta da return instance ile referansı döndür.


    çok absürd bi bi şekilde anlattım. bak c# videosu buldum tam bunu mükemmel bir şekilde anlatan. zaten diller çok farklı değil burdan mantığı çok rahat biçimde kaparsın.
    thread safe i de anlatıyor.

    http://www.csharpnedir.com/dotnettv/watch/?id=149&title=Design%20%20Patterns%20:%20Singleton
    silverlight lazım video player ın çalışması için. windows kullanmıyorsan ordan indirme linki var indirip izle derim. ben öyle yaptım.



    < Bu mesaj bu kişi tarafından değiştirildi Guest-E41040413 -- 16 Eylül 2011; 22:32:59 >




  • http://www.codeproject.com/KB/cpp/singletonrvs.aspx
    burada görüldüğü üzere olay şöyle.

    Sınıfın, içi boş private kurucusu olur. Böylece new ile örneklenmesi engellenir çünkü kurucu fonksiyon sınıfın dışından çağrılamaz. Sınıfın örneğini almak için bir static fonksiyon kullanılır (static olmak zorunda çünkü üye fonksiyona örnek olmadan erişilmez). Ayrıca sınıfta bir static bool değişkeni var. Eğer sınıfın bir örneği oluşursa true yapılır, eğer bu bayrak true ise yeni bir örnek alınmaz, var olanın adresi verilir. false ise yeni örnek oluşturulur. Nesne yok olurken bu bayrak false yapılır böylece aynı anda sadece bir nesne çalışabilir.




  • quote:

    Orijinalden alıntı: elektro_gadget

    http://www.codeproject.com/KB/cpp/singletonrvs.aspx
    burada görüldüğü üzere olay şöyle.

    Sınıfın, içi boş private kurucusu olur. Böylece new ile örneklenmesi engellenir çünkü kurucu fonksiyon sınıfın dışından çağrılamaz. Sınıfın örneğini almak için bir static fonksiyon kullanılır (static olmak zorunda çünkü üye fonksiyona örnek olmadan erişilmez). Ayrıca sınıfta bir static bool değişkeni var. Eğer sınıfın bir örneği oluşursa true yapılır, eğer bu bayrak true ise yeni bir örnek alınmaz, var olanın adresi verilir. false ise yeni örnek oluşturulur. Nesne yok olurken bu bayrak false yapılır böylece aynı anda sadece bir nesne çalışabilir.




    Linkdeki örnekte " new" ile heap bölgesinde alan tahsisi yapmış,programın devamında explicit veya implict olarak "delete" etmemiş.Her ne kadar işletim sistemi tarafından program sonlandırılığında silinse de teknik olarak "memory leak" oluşur.Hafizada çalışma zamanında bellek tahisisi yapıldıktan sonra,program'dan çıkmadan önce "delete" edilmesi alışkanlık edilmelidir.

    Bunun için aşağıdaki şekildeSingletonDestroy sinifi yazılarak new ile oluşturulan instance implicit olarak silinmelidir.Veya explicit olarak da silinebilir.

    Örnek:

     


    class Singleton {
    public:
    static Singleton* Instance();
    protected:
    Singleton() { }

    friend class SingletonDestroyer;
    virtual ~Singleton() { }
    private:
    static Singleton* _instance;
    static SingletonDestroyer _destroyer;
    };

    Singleton* Singleton::_instance = 0;
    SingletonDestroyer Singleton::_destroyer;

    Singleton* Singleton::Instance () {
    if (!_instance) {
    _instance = new Singleton;
    _destroyer.SetSingleton(_instance);
    }
    return _instance;
    }




     


    class SingletonDestroyer {
    public:
    SingletonDestroyer(Singleton* = 0);
    ~SingletonDestroyer();

    void SetSingleton(Singleton* s);
    private:
    Singleton* _singleton;
    };

    SingletonDestroyer::SingletonDestroyer (Singleton* s) {
    _singleton = s;
    }

    SingletonDestroyer::~SingletonDestroyer () {
    delete _singleton;
    }

    void SingletonDestroyer::SetSingleton (Singleton* s) {
    _singleton = s;
    }




    Alternatif olarak aşağıdaki şekilde yazılabilir.Bu şekilde "memory leak" oluşmamış olur.

    Not:Aşağıdaki uygulama "single thread" uygulamalar için çözümdür.Program sona erdiğinde işletim sistemi tarafından static değişkenler otomatik olarak yok edilir.


     


    //Singleton.h

    #ifndef Singleton_H
    #define Singleton_H

    #include <iostream>


    class Singleton
    {

    private:
    Singleton();
    ~Singleton();
    static bool isInit;
    int m_int;


    public:

    static Singleton* getInstance();
    void setInt(int i);
    int getInt();


    };


    #endif





     

    //Singleton.cpp

    #include "Singleton.h"

    bool Singleton::isInit=false;


    Singleton* Singleton::getInstance()
    {
    static Singleton s;
    return isInit? &s:0;
    }


    void Singleton::setInt(int i)
    {

    m_int=i;
    }

    int Singleton::getInt()
    {

    return m_int;

    }

    Singleton::Singleton()
    {

    isInit=true;

    }

    Singleton::~Singleton()
    {

    isInit=false;
    }




     


    //Main.cpp

    #include "Singleton.h"



    int main()
    {
    Singleton* p=Singleton::getInstance();

    p->setInt(5);

    Singleton* p2=Singleton::getInstance();

    std::cout<<"Int degeri p2 icinde:"<<p2->getInt()<<std::endl;


    system("pause");
    return 0;
    }





    Teknik detay için

    Edit:2 adet instance oluşturuldu,örnekleme için.Yazmayı unutmuşum.



    < Bu mesaj bu kişi tarafından değiştirildi fenasi44 -- 17 Eylül 2011; 7:43:14 >




  • Arkadaşlar cevaplarınız için çok teşekkürler.

    Olayı kavradım fakat bir teknik daha gördüm araştırırken, bu teknikte class yerine namespace kullanılıyor:

     
    namespace deneme
    {
    // burada public metodlar, degiskenler
    metod1();
    metod2();
    değişken1, değişken 2;
    ...
    ..
    .

    // Burada bu alana özel yani sınıflardaki private olayı gibi isimsiz bir namespace yaratılıyor
    namespace
    {
    // özel metodlar, degiskenler....
    }
    }


    Hem singletonu hemde namespace olayını test ettim ikiside çalışıyor ancak sizin fikrinizi almak istedim, hangisi daha iyidir?
  • Yapay Zeka’dan İlgili Konular
    Daha Fazla Göster
    
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.