Aracılığıyla paylaş


Nesne yaşam süresi ve kaynak yönetimi (RAII)

Yönetilen dillerden farklı olarak, C++ bir program çalışırken yığın belleğini ve diğer kaynakları serbest bırakan bir iç işlem olan otomatik çöp toplamaya sahip değildir. C++ programı, alınan tüm kaynakları işletim sistemine döndürmekten sorumludur. Kullanılmayan bir kaynağın serbest bırakılmaması sızıntı olarak adlandırılır. Sızdırılan kaynaklar, işlem çıkana kadar diğer programlar tarafından kullanılamaz. Özellikle bellek sızıntıları, C stili programlamadaki hataların yaygın bir nedenidir.

Modern C++ yığın üzerindeki nesneleri bildirerek yığın belleğini mümkün olduğunca kullanmaktan kaçınıyor. Bir kaynak yığın için çok büyükse, bir nesneye ait olmalıdır. Nesnesi başlatıldıkçe, sahip olduğu kaynağı alır. Nesne daha sonra kaynağı yok edicisinde serbest bırakmakla sorumludur. Sahip olan nesnenin kendisi yığında bildirilir. Nesnelerin kaynaklarına sahip olması ilkesi , "kaynak alımı başlatmadır" veya RAII olarak da bilinir.

Kaynağa sahip olan bir yığın nesnesi kapsam dışına çıktığında, yok edicisi otomatik olarak çağrılır. Bu şekilde, C++ dilinde çöp toplama nesne ömrüyle yakından ilişkilidir ve belirleyicidir. Bir kaynak her zaman programın bilinen bir noktasında serbest bırakılır ve bunu denetleyebilirsiniz. Yalnızca C++ içindekiler gibi belirlenimci yıkıcılar belleği ve bellek dışı kaynakları eşit şekilde işleyebilir.

Aşağıdaki örnekte basit bir nesnesi gösterilmektedir w. İşlev kapsamındaki yığında bildirilir ve işlev bloğunun sonunda yok edilir. Nesne w hiçbir kaynağa (yığın ayrılmış bellek gibi) sahip değildir. Tek üyesi g yığında bildirilir ve yalnızca ile wbirlikte kapsamın dışına çıkar. Yıkıcıda widget özel kod gerekmez.

class widget {
private:
    gadget g;   // lifetime automatically tied to enclosing object
public:
    void draw();
};

void functionUsingWidget () {
    widget w;   // lifetime automatically tied to enclosing scope
                // constructs w, including the w.g gadget member
    // ...
    w.draw();
    // ...
} // automatic destruction and deallocation for w and w.g
  // automatic exception safety,
  // as if "finally { w.dispose(); w.g.dispose(); }"

Aşağıdaki örnekte, w bir bellek kaynağı vardır ve bu nedenle, belleği silmek için yok edicisinde kod olmalıdır.

class widget
{
private:
    int* data;
public:
    widget(const int size) { data = new int[size]; } // acquire
    ~widget() { delete[] data; } // release
    void do_something() {}
};

void functionUsingWidget() {
    widget w(1000000);  // lifetime automatically tied to enclosing scope
                        // constructs w, including the w.data member
    w.do_something();

} // automatic destruction and deallocation for w and w.data

C++11'den bu yana, önceki örneği yazmanın daha iyi bir yolu vardır: standart kitaplıktan akıllı bir işaretçi kullanarak. Akıllı işaretçi, sahip olduğu belleği ayırma ve silme işlemlerini işler. Akıllı işaretçi kullanmak, sınıfında açık bir yıkıcı gereksinimini widget ortadan kaldırır.

#include <memory>
class widget
{
private:
    std::unique_ptr<int[]> data;
public:
    widget(const int size) { data = std::make_unique<int[]>(size); }
    void do_something() {}
};

void functionUsingWidget() {
    widget w(1000000);  // lifetime automatically tied to enclosing scope
                        // constructs w, including the w.data gadget member
    // ...
    w.do_something();
    // ...
} // automatic destruction and deallocation for w and w.data

Bellek ayırma için akıllı işaretçiler kullanarak bellek sızıntısı olasılığını ortadan kaldırabilirsiniz. Bu model, dosya tanıtıcıları veya yuvalar gibi diğer kaynaklar için çalışır. Kendi kaynaklarınızı sınıflarınızda benzer şekilde yönetebilirsiniz. Daha fazla bilgi için bkz . Akıllı işaretçiler.

C++ tasarımı, nesnelerin kapsamın dışına çıktığında yok edilmesini sağlar. Yani, bloklardan çıkılırken, inşaatın ters sırasına göre yok edilirler. Bir nesne yok edildiğinde, temelleri ve üyeleri belirli bir sırada yok edilir. Genel kapsamda herhangi bir bloğun dışında bildirilen nesneler sorunlara yol açabilir. Genel bir nesnenin oluşturucusunun özel durum oluşturması durumunda hata ayıklamak zor olabilir.

Ayrıca bkz.

C++ 'a yeniden hoş geldiniz
C++ dil başvurusu
C++ Standart Kitaplığı