Statik Metotlar ve Değişkenler
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 31 / 104.
Statik üyelerin tüm nesneler arasında paylaşıldığını öğrendiniz. Şimdi, statik değişkenlerle birlikte statik metotların nasıl düzgün bir şekilde tanımlanacağını ve kullanılacağını keşfedelim.
Bir sınıf içinde bildirilen statik değişkenler, genellikle bir kaynak dosyasında olmak üzere sınıfın dışında tanımlanmalıdır. Bunun nedeni, statik üyelerin tüm nesneler tarafından paylaşılan tam olarak bir depolama konumuna ihtiyaç duymasıdır:
class Counter {
static int count; // Sadece bildirim
public:
Counter() { count++; }
~Counter() { count--; }
static int getCount() { // Statik metot
return count;
}
};
// Tanımlama - sınıf dışında gereklidir
int Counter::count = 0;Bir statik metot herhangi bir nesneye değil, sınıfa aittir. Bunun önemli bir sonucu vardır: statik metotlar örnek üyelerine erişemez veya this işaretçisini kullanamazlar, çünkü belirli bir nesne üzerinde çağrılmazlar.
class MathUtils {
static double pi;
public:
static double circleArea(double radius) {
return pi * radius * radius; // Statik üyelere erişebilir
}
};
double MathUtils::pi = 3.14159;
// Bir nesne olmadan çağrılır
double area = MathUtils::circleArea(5.0);Statik metotlar; nesne durumuna ihtiyaç duymayan yardımcı fonksiyonlar, nesne oluşturan fabrika metotları veya statik verilere erişim için idealdir. Bir nesne örneği gerektirmedikleri için, onları sınıf adını ve kapsam çözünürlük operatörünü kullanarak çağırırsınız: ClassName::methodName().
Görev
KolayNesne örneklerine ihtiyaç duymadan sınıf düzeyinde işlevsellik sağlamak için statik metotların ve değişkenlerin nasıl birlikte çalıştığını gösteren benzersiz bir ID oluşturucu sistemi kuralım.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
IDGenerator.h: Sıralı benzersiz ID'ler üreten birIDGeneratorsınıfı tanımlayın. Sınıfınız şunlara sahip olmalıdır:- Atanacak bir sonraki ID'yi takip eden özel bir statik üye
nextId(1000'den başlar) - Tüm ID'ler için özelleştirilebilir bir önek saklayan özel bir statik üye
prefix(string) - Öneki değiştiren statik bir metot
setPrefix(const std::string& p) - Önek ile mevcut ID numarasını birleştiren bir string döndüren ve ardından bir sonraki çağrı için
nextIddeğerini artıran statik bir metotgetNextId() - Sayacı artırmadan bir sonraki ID'nin ne olacağını döndüren statik bir metot
peekNextId() - Kaç tane ID oluşturulduğunu döndüren statik bir metot
getGeneratedCount()(ipucu: başlangıç değeri ve mevcutnextIdüzerinden hesaplayın) nextIddeğerini tekrar1000'e sıfırlayan statik bir metotreset()
Statik üyelerinizi sınıf tanımından sonra sınıfın dışında tanımlamayı unutmayın.
prefixdeğerini"ID-"olarak başlatın.- Atanacak bir sonraki ID'yi takip eden özel bir statik üye
main.cpp: Herhangi bir nesne oluşturmadan sınıf adını kullanarak statik metotları çağırmayı gösterin. Girişten özel bir önek okuyun, ardından:peekNextId()kullanarak"Peek: <peeked_id>"yazdırıngetNextId()kullanarak üç ID oluşturun ve her birini"Generated: <id>"olarak yazdırın- Kaç ID oluşturulduğunu gösteren
"Count: <count>"yazdırın setPrefix()ile giriş değerini kullanarak öneki değiştirin- İki ID daha oluşturun ve her birini
"Generated: <id>"olarak yazdırın - Tekrar
"Count: <count>"yazdırın reset()metodunu çağırın"After reset - Peek: <peeked_id>"yazdırın"After reset - Count: <count>"yazdırın
Hiçbir zaman bir IDGenerator nesnesi oluşturmadığınıza dikkat edin — tüm metotlar IDGenerator::methodName() kullanılarak doğrudan sınıf üzerinden çağrılır. Bu, statik metotların temel özelliğidir: herhangi bir örneğe değil, sınıfın kendisine aittirler.
Başlık dosyanıza <string> ve <iostream> kütüphanelerini dahil edin ve başlık koruyucularını (header guards) unutmayın.
Kopya kağıdı
Bir sınıf içinde bildirilen statik değişkenler, sınıfın dışında tanımlanmalıdır. Statik üyeler, tüm nesneler tarafından paylaşılan tam olarak bir depolama konumuna ihtiyaç duyarlar:
class Counter {
static int count; // Sadece bildirim (Declaration)
public:
Counter() { count++; }
static int getCount() {
return count;
}
};
// Tanımlama - sınıf dışında gereklidir
int Counter::count = 0;Bir statik metot herhangi bir nesneye değil, sınıfa aittir. Statik metotlar, belirli bir nesne üzerinde çağrılmadıkları için örnek (instance) üyelerine erişemezler veya this işaretçisini kullanamazlar:
class MathUtils {
static double pi;
public:
static double circleArea(double radius) {
return pi * radius * radius; // Statik üyelere erişebilir
}
};
double MathUtils::pi = 3.14159;
// Bir nesne olmadan sınıf adı kullanılarak çağrılır
double area = MathUtils::circleArea(5.0);Statik metotlar, sınıf adı ve kapsam çözünürlük operatörü (scope resolution operator) kullanılarak çağrılır: ClassName::methodName(). Nesne durumuna ihtiyaç duymayan yardımcı (utility) fonksiyonlar, fabrika (factory) metotları veya statik verilere erişim için idealdirler.
Kendin dene
#include <iostream>
#include <string>
#include "IDGenerator.h"
using namespace std;
int main() {
// Girdiden özel öneki oku
string customPrefix;
cin >> customPrefix;
// TODO: peekNextId() kullanarak "Peek: <peeked_id>" yazdır
// TODO: getNextId() kullanarak üç ID oluştur ve her birini "Generated: <id>" olarak yazdır
// TODO: Kaç tane ID oluşturulduğunu gösteren "Count: <count>" yazdır
// TODO: setPrefix() ile girdi değerini kullanarak öneki değiştir
// TODO: İki ID daha oluştur ve her birini "Generated: <id>" olarak yazdır
// TODO: Tekrar "Count: <count>" yazdır
// TODO: reset() fonksiyonunu çağır
// TODO: "After reset - Peek: <peeked_id>" yazdır
// TODO: "After reset - Count: <count>" yazdır
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner