İçindekiler:

C++'da Singleton Tasarım Deseni Nasıl Yapılır: 9 Adım
C++'da Singleton Tasarım Deseni Nasıl Yapılır: 9 Adım

Video: C++'da Singleton Tasarım Deseni Nasıl Yapılır: 9 Adım

Video: C++'da Singleton Tasarım Deseni Nasıl Yapılır: 9 Adım
Video: Singleton Pattern Nedir ? | Design Patterns | Tasarım Kalıpları 2024, Haziran
Anonim
C++'da Singleton Tasarım Deseni Nasıl Yapılır?
C++'da Singleton Tasarım Deseni Nasıl Yapılır?

Tanıtım:

Bu talimat kılavuzunun amacı, kullanıcıya tekil tasarım deseninin C++ programında nasıl uygulanacağını öğretmektir. Bunu yaparken, bu komut seti ayrıca okuyucuya bir singleton'un öğelerinin neden böyle olduklarını ve kodun nasıl işlendiğini açıklayacaktır. Bunu bilmek, gelecekteki singleton'larınızda hata ayıklamada gelecekte yardımcı olacaktır. Singleton tasarım deseni nedir? Singleton tasarım deseni, kodlayıcının yalnızca bir kez başlatılabilen bir sınıf oluşturduğu bir tasarım desenidir, üstbilgi dosyasını projeyle ilgili diğer dosyalara #include etmiş olmanız koşuluyla, sınıfların genel işlevlerine temel olarak herhangi bir yerden erişilebilir.

Singleton tasarım kalıbı, herhangi bir nesne yönelimli programcı, yazılım programcısı ve oyun programcısı için bilinmesi gereken bir tasarım kalıbıdır. Singleton tasarım kalıbı aynı zamanda en kolay kodlama tasarım kalıplarından biridir. Bunu öğrenmek, gelecekte diğer, daha zor tasarım kalıplarını öğrenmenize yardımcı olabilir. Ayrıca, programınızın kodunu mümkün olmadığını düşündüğünüz şekillerde düzene sokmanıza da yardımcı olabilir.

Singleton tasarım kalıbının zorluğu diğer tasarım kalıplarına göre kolay olsa da bu komut seti orta zorluktadır. Bu, bu talimatları yapmak için C++'ın temel ve ileri sözdizimi gereksinimlerini bilmenizi öneririz. Ayrıca uygun C++ kodlama görgü kurallarını da bilmelisiniz (yani, sınıf değişkenlerini özel tutun, başlık dosyası başına bir sınıf vb.). Ayrıca C++'da belleği nasıl boşaltacağınızı ve yapıcıların ve yıkıcıların nasıl çalıştığını da bilmelisiniz.

Bu eğitim kılavuzu ortalama 10-15 dakika sürecektir.

Malzeme gereksinimleri:

-Visual Studios (herhangi bir sürüm) çalıştırabilen bir bilgisayar (PC veya Mac olabilir)

-Visual Studios'ta oluşturulmuş, singleton'unuzu test edebileceğiniz basit bir program

Not: Singleton tasarım deseni, IDE veya kodlama arabirimini destekleyen herhangi bir başka C++ üzerinde yapılabilir, ancak bu komut seti için Visual Studios Enterprise Edition kullanacağız.

Adım 1: Başlık Dosyası ve CPP Dosyası ile Sınıfınızı Oluşturun

Başlık Dosyası ve CPP Dosyası ile Sınıfınızı Oluşturun
Başlık Dosyası ve CPP Dosyası ile Sınıfınızı Oluşturun
Başlık Dosyası ve CPP Dosyası ile Sınıfınızı Oluşturun
Başlık Dosyası ve CPP Dosyası ile Sınıfınızı Oluşturun

Bu iki dosyayı ve sınıfı bir kerede oluşturmak için projenizi / programınızı Visual Studios'ta açın, çözüm gezginine gidin, sağ tıklayın ve fare imlecinizin yanında bir kutu görünmelidir, "Ekle" seçeneğini bulun, üzerine gelin üzerinde ve sağda başka bir kutu görünmelidir. Bu kutuda “Yeni Öğe..” seçeneğini bulmak istiyorsanız, tıklayın ve aşağıdaki fotoğraf 1.1 görüntüsüne benzeyen bir pencere görünmelidir. Bu pencerede “C++ Class”ı seçin ve ardından “Ekle”ye basın. Bu, fotoğraf 1.2 görüntüsüne benzeyen başka bir pencere açacaktır. Bu pencerede, “Class Name” alanına sınıfınızın adını yazarsınız ve Visual Studios otomatik olarak gerçek dosyaya sınıf adından sonra isim verir. Bu talimatın amacı için, sınıfımıza “EngineDebugSingleton” adını vereceğiz, ancak bu herhangi bir harf tabanlı isim olabilir. Artık “Tamam”a basabilir ve 2. adıma geçebilirsiniz.

Not: Çözüm gezgini ve bilgisayarınızda dosyaların tutulduğu yer ayrıdır. Çözüm gezgininde herhangi bir şey taşımak veya oluşturmak, işletim sistemi dosya gezgini içindeki dosyaları taşımaz veya düzenlemez. Dosyalarınızı dosya gezgini tarafında organize etmenin güvenli bir yolu, kaldırmak olacaktır, ancak belirli dosyaları çözüm gezgininden silmeyin, aynı dosyaları dosya gezgininde istediğiniz konuma taşıyın ve ardından çözüm gezginine geri dönün, sağ tıklayın, “Ekle” seçeneğini bulun, ardından “Mevcut Öğe”yi bulun ve taşıdığınız dosyaları bulun. Hem üstbilgiyi hem de cpp dosyasını taşıdığınızdan emin olun.

Adım 2: Yapıcıyı Özel Olarak Ayarlayın

Yapıcıyı Özel Olarak Ayarlayın
Yapıcıyı Özel Olarak Ayarlayın

Yeni oluşturduğunuz CPP dosyanız ve başlık dosyanız ile, oluşturduğunuzda otomatik olarak açılmadıysa, çözüm gezginine gidin ve “EngineDebugSingleton.h” dosyasını tıklayın ve açın. Ardından, sınıfın varsayılan kurucusu olan bir "EngineDebugSingleton()" ve sınıf yıkıcısı olan "~EngineDebugSingleton()" ile karşılaşacaksınız. Bu adım için, yapıcıyı özel olarak ayarlamak isteyeceğiz, bu, bu işlevin yalnızca sınıf tarafından kullanılabilir olduğu ve başka bir şey olmadığı anlamına gelir. Bununla, sınıfın dışında sadece sınıfların başlık dosyasında ve sınıfların diğer işlevlerinde bir değişken oluşturamaz veya sınıfı belleğe tahsis edemezsiniz. Yapıcının özel olması, tasarım modelinin ve singleton'ların nasıl çalıştığının anahtarıdır. Gelecekteki adımlarda bir singleton'un nasıl başlatıldığını ve erişildiğini keşfedeceğiz.

Oluşturucuyu özel konuma getirdikten sonra sınıf şimdi böyle görünmelidir (İlgili fotoğrafa bakın)

Adım 3: Yıkıcıyı Özel Olarak Ayarlayın

Yıkıcı'yı Özel Olarak Ayarlayın
Yıkıcı'yı Özel Olarak Ayarlayın

yapıcı ile yaptığımız gibi

2. adım, bu adım için şimdi yıkıcıyı private olarak ayarlayacağız. Yapıcıda olduğu gibi, sınıfın kendisi dışında hiçbir şey sınıfın değişkenlerini bellekten silemez.

Bu adımı tamamladıktan sonra sınıf şimdi böyle görünmelidir. (Bkz. İlişkili fotoğraf)

Adım 4: Singleton'da Statik İşaretçi Değişkeni Oluşturma

Singleton'da Statik İşaretçi Değişkeni Oluşturma
Singleton'da Statik İşaretçi Değişkeni Oluşturma

Bu adımda, bir oluşturacağız

"EngineDebugSingleton*" türündeki statik işaretçi değişkeni. Bu, singletonumuzu belleğe tahsis etmek için kullanılacak değişken olacak ve singletonumuzun belleğe tahsis edildiği süre boyunca ona işaret edecek.

Bu değişkeni oluşturduktan sonra başlık dosyamız böyle görünmelidir.

Adım 5: Bir Örnek İşlevi Oluşturma

Örnek İşlev Oluşturma
Örnek İşlev Oluşturma

Şimdi bir örnek yapmak istiyoruz

işlev. İşlevin statik bir işlev olması gerekecek ve sınıfımıza bir başvuru döndürmek isteyecektir (“EngineDebugSingleton&”). Fonksiyonumuzu Instance() olarak adlandırdık. Fonksiyonun kendisinde, ilk önce ptrInstance == nullptr (!ptrInstance olarak kısaltılabilir) olup olmadığını test etmek isteyeceğiz, eğer nullptr ise bu, singleton'un tahsis edilmediği anlamına gelir ve if ifadesinin kapsamında, ptrInstance = new EngineDebugSingleton() yaparak tahsis etmek istiyorum. Burası aslında singleton'u belleğe ayırdığınız yerdir. if ifadesinin kapsamından çıktıktan sonra, “*ptrInstance” sözdizimi ile gösterilen ptrInstance'ın işaret ettiği şeyi döndüreceğiz. Statik genel işlevlerimizi yaparken bu işlevi yoğun bir şekilde kullanacağız, böylece singleton'un oluşturulup oluşturulmadığını ve belleğe ayrılıp ayrılmadığını kontrol edebiliriz. Özünde, bu işlev, sınıfın yalnızca bir tahsisine sahip olmanızı sağlar ve daha fazlasına sahip olamazsınız.

Instance() fonksiyonunu oluşturduktan sonra sınıfımız şimdi böyle görünmelidir. Gördüğünüz gibi, yaptığımız her şey sınıfın özel bölümünde kaldı, sonraki birkaç adımda bu biraz değişecek.

Adım 6: Statik Genel İşlevler Oluşturma

Statik Genel İşlevler Oluşturma
Statik Genel İşlevler Oluşturma
Statik Genel İşlevler Oluşturma
Statik Genel İşlevler Oluşturma
Statik Genel İşlevler Oluşturma
Statik Genel İşlevler Oluşturma

Fonksiyonu şuradan yaptıktan sonra

adım 5, statik genel işlevler yapmaya başlayabilirsiniz. Her genel işlevin onunla birlikte gidecek özel bir işlevi olmalıdır, bu işlevin adı aynı olamaz. İşlev neden Statik olsun? Genel işlevleri statik hale getiriyoruz, böylece gerçek bir nesne olmadan erişilebilirler. Yani “EngineDebugSingleObj->SomeFunction()” gibi bir şey yapmak yerine “EngineDebugSingleton:: Some Function()” yapıyoruz. Bu, başlık dosyasını birlikte çalıştığınız belirli proje dosyasına dahil etmiş olmanız koşuluyla, bir singleton'a temelde kodun herhangi bir yerinden erişilmesini mümkün kılar. Bununla, singleton'u herhangi bir genel işlevi aracılığıyla da oluşturabilirsiniz.

Bu adımdaki amaçlarımız için iki genel statik boşluk işlevi yarattık, “add()” ve “çıkartma()”. Özel bölümde, “PrivAdd()” ve “PrivSubtract()” olmak üzere iki fonksiyonumuz daha var. Ayrıca “NumberOfThings” adında bir int değişkeni ekledik. Bu işlevlerin tanımı sınıflarımızın CPP dosyasına girecektir. Fonksiyonun CPP dosyasına kolayca girmesini sağlamak için, altında yeşil bir çizgi olması gereken fonksiyonu imlecinizle vurgulayın ve “Sol ALT + ENTER” a basın, size tanımda oluşturma seçeneğini verecektir. sınıfların ilişkili CPP dosyası. Başlık dosyasının nasıl görünmesi gerektiğini görmek için Fotoğraf 6.1'e bakın ve tüm işlev tanımlarını oluşturduktan sonra, işlev tanımlarınızın içinde kod olmaması dışında CPP'niz Fotoğraf 6.2 gibi görünmelidir.

Artık fonksiyon tanımlarınıza Fotoğraf 6.2'deki kodun aynısını eklemek isteyeceksiniz. Daha önce belirtildiği gibi, genel işlevlerimiz, ptrInstance'ın işaret ettiği şeyi döndürecek olan Instance() işlevini kullanacak. Bu, sınıfımızın özel işlevlerine erişmemizi sağlar. Herhangi bir singleton'ın genel işleviyle, yalnızca bu Örnek işlevini çağırıyor olmalısınız. Bunun tek istisnası, Sonlandırma işlevimizdir.

Not: Bu adımda gösterilen tam genel ve özel işlevler gerekli değildir, özel işlevde farklı işlev adlarına ve işlemlere sahip olabilirsiniz, ancak herhangi bir genel işlev türü için, onunla birlikte gitmek için özel bir işleve sahip olmalısınız ve public işlevi bizim durumumuzda her zaman Instance() işlevini kullanmalıdır.

Adım 7: Sonlandırma İşlevini Oluşturma

Sonlandırma İşlevini Oluşturma
Sonlandırma İşlevini Oluşturma
Sonlandırma İşlevini Oluşturma
Sonlandırma İşlevini Oluşturma

Sınıfımızda sadece singletonumuzu bellekten ayırabildiğimiz için statik bir public function oluşturmalıyız. Bu işlev, sınıf yıkıcıyı çağıran ptrInstance üzerinde delete öğesini çağıracak ve ardından programınız sona ermezse yeniden tahsis edilebilmesi için ptrInstance'ı nullptr olarak ayarlamak isteyeceğiz. Ayrıca, herhangi bir Singleton'ın özel değişkenlerinde ayırdığınız ayrılmış belleği temizlemek için Singleton'larınızı sonlandırmak isteyeceksiniz.

Adım 8: PtrInstance'ı Nullptr olarak Ayarlama

PtrInstance'ı Nullptr'ye Ayarlama
PtrInstance'ı Nullptr'ye Ayarlama

Singletonunuzu tamamlamak için EngineDebugSingleton. CPP dosyasına gitmek istiyorsunuz ve CPP dosyasının en üstüne, örneğimizde “EngineDebugSingleton* EngineDebugSingleton::ptrInstance = nullptr” yazın.

Bunu yapmak başlangıçta ptrInstance'ı nullptr olarak ayarlayacaktır, bu nedenle ilk kez instance işlevinden geçtiğinizde, sınıfımızın belleğe ayrılmasına izin verilecektir. Onsuz, büyük olasılıkla bir hata alırsınız çünkü kendisine tahsis edilmiş hiçbir şeyi olmayan belleğe erişmeye çalışacaksınız.

9. Adım: Test ve Sonuç

Test ve Sonuç
Test ve Sonuç

Şimdi, çalıştığından emin olmak için singleton'umuzu test etmek isteyeceğiz, bu, 6. adımda açıklandığı gibi genel işlevleri çağırmamızı içerecek ve kodunuzda adım adım ilerlemek için kesme noktaları ayarlamanızı ve singleton'un şu şekilde çalıştığını görmenizi öneririz. olmalı. Başlangıç noktamız projemizin main.cpp'si olacak ve main.cpp'miz artık aşağıdaki resimdeki gibi görünüyor.

Tebrikler! Singleton Design Pattern'in ilk uygulamasını yeni tamamladınız. Bu tasarım deseni ile artık kodunuzu çeşitli şekillerde düzenleyebilirsiniz. Örneğin, artık programınızın çalışma süresi boyunca çalışan ve sınıfı dahil ettiğiniz her yerde statik işlevler aracılığıyla erişilebilen yönetici sistemleri yapabilirsiniz.

Son başlık dosyanız fotoğraf 7.1 gibi görünmelidir. Singleton'ınızla ilişkili CPP dosyanız, dosyanın üst kısmında 8. adımda gösterilen kodun eklenmesiyle Fotoğraf 6.2'ye benzemelidir. Bu talimat size Singleton Tasarım Modelinin basit bir yapısını sağlamıştır.

Sorun Giderme Önerisi:

Bellekle ilgili hatalar mı alıyorsunuz?

ptrInstance'ı nullptr olarak ayarladığınızdan emin olmak için 7. ve 8. adıma başvurduğunuzdan emin olun.

Sonsuz döngü meydana geliyor mu?

Genel işlevler için tanımlarında, aynı genel işlevi değil, özel işlevi aradığınızdan emin olun.

Singleton içinde ayrılan nesneler bellek sızıntılarına neden oluyor mu?

Program kodunuz içinde uygun olduğunda singleton'ınızın sonlandırma işlevini çağırdığınızdan ve singleton'ınızın yıkıcısında, singleton kodu kapsamında belleğe tahsis edilmiş tüm nesneleri ayırdığınızdan emin olun.