Aşağıdakiler elbette tam olarak kesin değildir. Okuduğunuzda bir tuz tanesi ile alın :)
Bahsettiğiniz üç şey , nesnelerin ne kadar yaşayacağı ve hayata ne zaman başladığıyla ilgili olan otomatik, statik ve dinamik depolama süresidir .
Otomatik saklama süresi
Kısa süreli ve küçük veriler için otomatik depolama süresini kullanırsınız ; bu, yalnızca bazı bloklar için yerel olarak gereklidir :
if(some condition) {
int a[3]; // array a has automatic storage duration
fill_it(a);
print_it(a);
}
Ömür bloktan çıkar çıkmaz biter ve nesne tanımlanır tanımlanmaz başlar. Bunlar en basit depolama süresidir ve özellikle dinamik depolama süresinden çok daha hızlıdır.
Statik saklama süresi
Statik depolama süresini, kapsamı bu tür kullanıma izin veriyorsa (ad alanı kapsamı) herhangi bir kod tarafından her zaman erişilebilen değişkenler ve ömrünü kapsamlarının dışına (yerel kapsam) genişletmesi gereken yerel değişkenler için kullanırsınız ve sınıflarındaki tüm nesneler tarafından paylaşılması gereken üye değişkenler için (sınıf kapsamı). Kullanım ömürleri bulundukları kapsama bağlıdır. Ad alanı kapsamına , yerel kapsam ve sınıf kapsamına sahip olabilirler . Her ikisi için de doğru olan, hayatları başladığında, programın sonunda yaşamın sona ermesidir . İşte iki örnek:
// static storage duration. in global namespace scope
string globalA;
int main() {
foo();
foo();
}
void foo() {
// static storage duration. in local scope
static string localA;
localA += "ab"
cout << localA;
}
Program yazdırır ababab
, çünkü localA
bloğunun çıkışından sonra yok olmaz. Yerel kapsamı olan nesnelerin, denetim tanımlarına ulaştığında ömür boyu başladığını söyleyebilirsiniz . Çünkü localA
işlevin gövdesi girildiğinde olur. Ad alanı kapsamındaki nesneler için, ömür boyu program başlangıcında başlar . Aynı şey sınıf kapsamındaki statik nesneler için de geçerlidir:
class A {
static string classScopeA;
};
string A::classScopeA;
A a, b; &a.classScopeA == &b.classScopeA == &A::classScopeA;
Gördüğünüz gibi classScopeA
, sınıfının belirli nesnelerine değil, sınıfın kendisine bağlıdır. Yukarıdaki üç adın adresi aynıdır ve hepsi aynı nesneyi gösterir. Statik nesnelerin ne zaman ve nasıl başlatıldığına dair özel bir kural vardır, ancak şimdi bununla ilgilenmeyelim. Bu statik başlatma siparişi fiyasko terimi ile kastedilmektedir .
Dinamik depolama süresi
Son saklama süresi dinamiktir. Nesneleri başka bir adada yaşamak istiyorsanız ve bu referansların etrafına işaretçiler koymak istiyorsanız bunu kullanırsınız. Nesneleriniz büyükse ve yalnızca çalışma zamanında bilinen boyut dizileri oluşturmak istiyorsanız bunları da kullanırsınız . Bu esneklik nedeniyle, dinamik depolama süresine sahip nesnelerin yönetimi karmaşık ve yavaştır. Bu dinamik süreye sahip nesneler, uygun bir yeni operatör çağrısı olduğunda ömür boyu başlar :
int main() {
// the object that s points to has dynamic storage
// duration
string *s = new string;
// pass a pointer pointing to the object around.
// the object itself isn't touched
foo(s);
delete s;
}
void foo(string *s) {
cout << s->size();
}
Ömrü yalnızca onlar için sil komutunu aradığınızda sona erer . Bunu unutursanız, bu nesneler ömür boyu asla bitmez. Ve kullanıcı tarafından bildirilen bir kurucu tanımlayan sınıf nesnelerinin yıkıcıları çağrılmaz. Dinamik depolama süresine sahip nesneler, kullanım ömürlerinin ve ilişkili bellek kaynaklarının manuel olarak işlenmesini gerektirir. Kütüphanelerin kullanımı kolaylaşır. Akıllı bir işaretçi kullanılarak belirli nesneler için açık çöp toplama oluşturulabilir:
int main() {
shared_ptr<string> s(new string);
foo(s);
}
void foo(shared_ptr<string> s) {
cout << s->size();
}
Silme çağrısını önemsemek zorunda değilsiniz: Nesneye başvuran son işaretçi kapsam dışına çıkarsa, paylaşılan ptr bunu sizin için yapar. Paylaşılan ptr otomatik depolama süresine sahiptir. Yani onun ömrü otomatik olarak yönetilir, bu onun yıkıcı dinamik nesnesine sivri silmesi gerekip gerekmediğini kontrol etmek için izin. Paylaşılan_ptr referansı için destek belgelerine bakın: http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm