C nesne imha
Tam olarak nesneleri C yok edilir , ve bu ne anlama geliyor? Çöp Toplayıcı yok beri elle yok etmek zorunda mıyım? Nasıl özel durumlar devreye girer?
CEVAP
Aşağıdaki metinde ayırt edeceğimkapsamlı nesnelerstatik olarak kapsayan kapsamı (fonksiyonlar, blok, sınıfları, ifadeler) tarafından belirlenen ve ., ^em>dinamik nesnelergenellikle çalışma zamanı kadar pek bilinmeyen.,
Sınıf nesneleri imha semantiği yıkıcılar tarafından belirlenirken, skaler bir nesne imha her zaman bir no-op. Özellikle, işaretçi değişken tahrip ediyordeğilbu pointee yok.
Kapsamlı nesneler
otomatik nesneler
Otomatik nesneleri (genellikle olarak anılacaktır "yerel değişkenler"), kontrol akış tanımının kapsamı ayrıldığında onların tanımı, ters sırayla yer yok
void some_function()
{
Foo a;
Foo b;
if (some_condition)
{
Foo y;
Foo z;
} <--- z and y are destructed here
} <--- b and a are destructed here
Eğer bir istisna bir işlev yürütülürken atılırsa, daha önce inşa otomatik nesneler dışında arayan yayılır önce tahrip edilir. Bu süreç denirgevşemek yığını. Yığın çözülme sırasında, başka bir istisna daha önce inşa edilen söz konusu otomatik nesnelerin yıkıcı bırakabilir. Aksi takdirde, 8 ** işlev olarak adlandırılır.
Bu C en önemli faktörlerden biri neden olur
Yıkıcılar asla atmak gerekir.
yerel olmayan statik nesneler
Statik nesneler ad kapsamında tanımlanmış (yaygın olarak "genel değişkenler") ve statik veri üyeleri, kendi tanımı, main
yürütülmesini sonra ters sırayla yer yok
struct X
{
static Foo x; // this is only a *declaration*, not a *definition*
};
Foo a;
Foo b;
int main()
{
} <--- y, x, b and a are destructed here
Foo X::x; // this is the respective definition
Foo y;
Statik nesneleri farklı çeviri birimleri olarak tanımlanan inşaat (ve yıkım) göreli sırasını tanımsız olduğunu unutmayın.
Eğer bir istisna statik bir nesnenin yıkıcı bırakırsa, std::terminate
denilen bir işlemdir.
yerel statik nesneler
Statik nesneler fonksiyonlar (ve eğer) akış kontrolü ilk kez kendi tanımı geçerken inşa edilir içinde tanımlanmış.1
main
yürütülmesini sonra: tersten tahrip ediyorlar
Foo& get_some_Foo()
{
static Foo x;
return x;
}
Bar& get_some_Bar()
{
static Bar y;
return y;
}
int main()
{
get_some_Bar().do_something(); // note that get_some_Bar is called *first*
get_some_Foo().do_something();
} <--- x and y are destructed here // hence y is destructed *last*
Eğer bir istisna statik bir nesnenin yıkıcı bırakırsa, 14 ** işlev olarak adlandırılır.
temel sınıf subobjects ve üye subobjects
Kontrol akış bir nesne, üye subobjects yıkıcı vücuttan çıkınca (aynı zamanda olarak bilinen "veri üyeleri") tanımlarına ters sırada vuruldu. Bundan sonra, temel sınıf subobjects temel-belirleyici-liste ters sırada vuruldu
class Foo : Bar, Baz
{
Quux x;
Quux y;
public:
~Foo()
{
} <--- y and x are destructed here,
}; followed by the Baz and Bar base class subobjects
Bir istisna sırasında atılırinşaatFoo
'In subobjects, daha sonra önceden oluşturulmuş tüm subobjects dışında yayılır önce tahrip olacaktır. Foo
yıkıcı, diğer taraftandeğilinfaz edilecek, Foo
nesne asla tam olarak inşa edilmiştir beri.
Yıkıcı vücut veri üyeleri kendilerini tahrip sorumlu değildir unutmayın. Sadece ihtiyaç için yazmak bir yıkıcı bir veri üyesi için bir tanıtıcı bir kaynak ihtiyaçları için serbest zaman nesne yok (gibi bir dosya, bir yuva, bir veritabanı bağlantısı, bir dışlama veya yığın bellek).
dizi elemanları
Dizi elemanları büyükten küçüğe yok. Bir istisna sırasında atılırinşaatn-inci elemanı, 0 unsurları n-1 hariç yayılır önce tahrip edilir.
geçici nesneler
Geçici bir nesne sınıfı türü prvalue bir ifade değerlendirildiğinde inşa edilmiştir. Prvalue bir ifade en belirgin örneğidir değer bir nesneyi döndüren işlevi, T operator (const T&, const T&)
gibi çağrı. Normal şartlar altında, geçici nesne lexically bu prvalue içeren tam ifade tamamen değerlendirildiğinde yok
__________________________ full-expression
___________ subexpression
_______ subexpression
some_function(a " " b);
^ both temporary objects are destructed here
Yukarıdaki işlev çağrısı some_function(a " " b)
daha büyük bir ifadenin parçası değildir, çünkü tam ifade (bunun yerine, deyim-deyim bir parçası). Dolayısıyla, taşıyıcının değerlendirilmesi sırasında oluşturulmuş tüm nesneler geçici noktalı virgül de yok olacak. Böyle iki geçici nesneler vardır: ilk önce eklenmesi sırasında inşa edilmiştir, ve ikinci, ikinci ek sırasında inşa edilmiştir. İkinci geçici nesne ilk önce tahrip olacaktır.
Eğer bir istisna ikinci sırasında ayrıca atılırsa, önce geçici bir nesne düzgün hariç yayılıyor önce tahrip olacaktır.
Eğer yerel bir referans prvalue bir ifade ile başlatıldı, geçici nesnenin ömrü sarkan bir referans alamazsın yani yerel referans kapsamı genişletilmiştir
{
const Foo& r = a " " b;
^ first temporary (a " ") is destructed here
// ...
} <--- second temporary (a " " b) is destructed not until here
Eğer sınıf olmayan tip prvalue bir ifade olarak değerlendirilir, sonuçdeğergeçici bir nesne değil. Ancak, geçici bir nesneeğer prvalue bir referans başlatmak için kullanılır oluşturulması:
const int& r = i j;
Dinamik nesneleri ve diziler
Aşağıdaki bölümdeX yok"ilk X imha ve temel bellek serbest bırakın"demektir. Aynı şekildeX oluşturun"ilk yeterli bellek ayrılamadı ve X yapı var" demektir.
dinamik nesneler
Dinamik bir nesne p = new Foo
ile oluşturulan delete p
ile yok edilir. delete p
, unutmayın eğer kaynak bir sızıntı var. Asla hepsi tanımsız davranışa neden beri aşağıdakilerden birini yapmak için çalışacağız.
delete[]
ile dinamik bir nesne (not köşeli parantez),free
veya başka bir anlamı yok- dinamik bir nesne birden çok kez yok
- yok edildikten sonra dinamik bir nesne erişimi
Bir istisna sırasında atılırinşaatdinamik bir nesne, temel hafıza hariç yayılır önce serbest bırakılır. (Yıkıcı olacaktırdeğilnesne asla tam olarak inşa edildi çünkü bellek serbest bırakmak için önce yürütülür.)
dinamik bir dizi
Dinamik bir dizi p = new Foo[n]
ile oluşturulan delete[] p
(not köşeli parantez) yok. delete[] p
, unutmayın eğer kaynak bir sızıntı var. Asla hepsi tanımsız davranışa neden beri aşağıdakilerden birini yapmak için çalışacağız.
delete
,free
veya başka yollarla dinamik bir dizi yok- dinamik bir dizi birden çok kez yok
- yok edildikten sonra dinamik bir dizi erişim
Bir istisna sırasında atılırinşaatn-inci elemanı, elemanları n-1 0 azalan şekilde tahrip oldu, temel bellek serbest bırakılır ve bu durum yayılır.
(Genellikle dinamik bir dizi için Foo*
std::vector<Foo>
tercih etmelisiniz. Doğru ve sağlam kod yazmak çok daha kolay hale getirir.)
başvuru sayma akıllı işaretçiler
Dinamik bir nesne std::shared_ptr<Foo>
çeşitli nesneler tarafından yönetilen std::shared_ptr<Foo>
son nesne dinamik nesne paylaştığın dahil yıkımı sırasında yok edilir.
(Genel olarak Paylaşılan Nesneler için Foo*
std::shared_ptr<Foo>
tercih etmelisiniz. Doğru ve sağlam kod yazmak çok daha kolay hale getirir.)
Vs null bir nesne İmha ayarı()...
O'un yeni yapılar yerine düz eski...
Arayüzleri java Nesne sınıfından yap...
C# Nesne Türü Karşılaştırma...
Neden bir HashMap daha hızlı bir Nesne...