Bu Not, mfc rutinleri bir dosyada depolandığında kalıcı c++ nesneleri ve nesne verilerin biçimini destekleyen açıklar. Bu yalnızca DECLARE_SERIAL ve IMPLEMENT_SERIAL makrolar sınıfları için geçerlidir.
Sorunu
Mfc uygulanması için kalıcı veri birçok nesne verilerini bir tek bitişik bölümünde bir dosyaya kaydetmek için kompakt ikili biçimde kullanır. Verinin nasıl saklandığı için bu ikili biçimde yapısı sağlar, ancak bu nesne tarafından kaydedilmiş fiili verileri sağlayan nesnenin Serialize üye işlevi.
Mfc, CArchivesınıfını kullanarak yapılandırmak sorunu çözdü. CArchive nesnesi, CArchive::Close üye işlevi, programcı tarafından açıkça veya örtülü olarak CArchive içeren kapsamlı çıkıldığı zaman yıkıcıyı kadar arşiv andan itibaren süren kalıcılığı için bir içerik oluşturulur sağlar.
Bu Not, CArchive üyeleri ReadObject ve WriteObjectuygulanması anlatılmaktadır. ReadObject ve WriteObject olmayan adlandırılır doğrudan ile otomatik olarak DECLARE_SERIAL ve IMPLEMENT_SERIAL makrolar tarafından üretilen sınıfın özel tür-güvenli ekleme ve çıkarma operatörleri tarafından kullanılır.
cMyObject sınıfı: Genel CObject
{
nbsp; DECLARE_SERIAL(CMyObject)
};
IMPLEMENT_SERIAL (CMyObj, CObject, 1)
/ / Örnek kullanım (ar ise bir CArchive &)
CMyObject * pObj;
CArchive & ar;
ar << pObj; / / ar çağırır.WriteObject(pObj)
ar >> pObj; / / ar çağırır.ReadObject(RUNTIME_CLASS(CObj))
Bu Not mfc kaynak dosyası arcobj kodunu tanımlar.CPP. Ana CArchive uygulanması, arccore bulunabilir.CPP.
Mağaza (CArchive::WriteObject) nesneleri kaydetme
Üye işlevi CArchive::WriteObject nesneyi yeniden oluşturmak için kullanılan üstbilgisi verileri yazıyor. Bu veriler iki bölümden oluşur: nesnenin türünü ve nesne durumu. Bu üye işlevi de böylece işaretçileri (dairesel işaretçiler dahil) nesne sayısına bakılmaksızın tek bir kopyası kaydedilir, yazılı olan nesnenin kimliği bakımından sorumlu.
(Ekleme) tasarruf ve (ayıklama) nesneleri geri birkaç "bildirim sabitleri üzerinde." Bunlar, ikili biçimde depolanır ve önemli bilgileri arşiv (16-bit miktarları "w" önekini gösterir Not) değerlerdir:
| Etiket | Açıklama |
| wNullTag | Null nesne işaretçisi (0) için kullanılan. |
| wNewClassTag | Aşağıdaki sınıf açıklaması bu arşiv context—(-1) için yeni olduğunu gösterir. |
| wOldClassTag | Bu bağlamda (0x8000) okunan nesne sınıfı görülmüştür gösterir. |
Nesneleri saklarken, arşiv saklı bir nesneden bir eşleme için bir 32-bit kalıcı tanımlayıcı (PID) olan bir CMapPtrToPtr ( m_pStoreMap) tutar. Bir PID her benzersiz nesne ve arşiv bağlamında kaydedilen her benzersiz sınıf adı atanır. Bu PID sırayla 1 başlayan teslim. Bu PID arşiv kapsamı dışında hiçbir öneme sahip ve özellikle kayıt numarası veya başka kimlik öğeleri ile karıştırılmamalıdır vardır unutmayın önemlidir.
CArchive sınıfı mfc sürüm 4.0 ile başlayarak, çok büyük arşiv desteklemek için genişletilmiştir. Önceki sürümlerde, bir PID arşiv-e doğru 0x7FFE (32766) nesneleri sınırlayan bir 16-bit miktarı oldu. PID şimdi 32-gem, ama onlar 0x7FFE büyük olan sürece onlar 16 bit yazılır. Büyük PID, 32-bit PID tarafından takip 0x7FFF olarak yazılır. Bu teknik dosya geriye dönük uyumluluğu korur.
Arşiv (genellikle aracılığıyla küresel ekleme işleci) nesneyi kaydetmek için bir istek yapıldığında, onay için null CObject imleci yapılır; İşaretçi null ise, wNullTag arşiv akışı içine eklenir.
Biz bir gerçek nesne işaretçisi serialized varlık yeteneğine sahip (sınıf DECLARE_SERIAL sınıf olduğunu), sonra m_pStoreMap nesne zaten kaydedilmiş eğer görmek için kontrol edin. Varsa, bu nesneyle ilişkili 32 bitlik PID eklemek.
Nesneyi önce kaydedilmemiş, dikkate almak gerekir iki ihtimal vardır: Bu arşivi içeriğe yeni tam (yani sınıf) nesnenin türünü ve nesne veya nesne zaten görülen bir tam türüdür. Biz biz kaydediyorsanız nesneyle ilişkili CRuntimeClass nesnesi ile eşleşen bir CRuntimeClass nesnesi için m_pStoreMap sorgu türü görülmüştür, belirlemek için. Bu sınıf önce gördüğümüz WriteObject wOldClassTag ve bu dizin temelinde sürümünden olan bir etiket ekler. CRuntimeClass bu arşivi içeriğe yeni ise, sonra WriteObject o sınıfın yeni bir PID atar ve wNewClassTag değeri öncesinde Arşivi, takın.
Bu sınıf tanımlayıcısı sonra arşiv deposu CRuntimeClass üye işlevi kullanılarak eklenir. CRuntimeClass::Store sınıfı (aşağıya bakınız) şema sayısı ve sınıf ASCII metin adını ekler. Not: ASCII metin adı kullanımı uygulamalarında arşiv benzersizliğini garanti etmez, dolayısıyla bozulmasını önlemek için veri dosyalarınızı etiketlemek için tavsiye edilir. Sınıf bilgisi ekleme, arşiv nesne m_pStoreMap yerleştirir ve sonra sınıf özgü veri arşivine eklemek Serialize üye işlevini çağırır. Nesneyi Serialize çağırmadan önce m_pStoreMap yerleştirerek nesnenin birden çok kopyasını saklamak için kaydedilmesini engeller.
İlk çağrıyı (genellikle ağ nesneleri kökü) döndürürken, yakın arşiv önemlidir. Diğer CFile işlemlerinin yapılması kullanacaksanız, CArchive üye işlev Flush çağrılmalıdır. Aksi takdirde bozuk bir arşiv neden olur.
&Notnbsp; Bu uygulama 0x3FFFFFFE endeksi başına arşiv içeriği kesin bir sınır getirir. Bu sayı benzersiz nesneleri ve tek bir arşiv kaydedilebilir sınıflar en fazla sayısını gösterir, ama tek bir dosya diske Not arşiv bağlamlarda sınırsız sayıda olabilir.
Nesneleri (CArchive::ReadObject) deposundan yükleme
(Ayıklama) nesnelerini yükleme CArchive::ReadObject üye işlevini kullanır ve WriteObjectconverse olduğunu. Olarak WriteObjectile ReadObject doğrudan kullanıcı koduna göre olarak değil; kullanıcı kodu ReadObject beklenen CRuntimeClassile arama türü için güvenli çıkarma operatörü aramak gerekir. Bu ayıklama işlemi türü bütünlüğünü sigortalanır.
WriteObject uygulanması artan PID atanan beri 1'den başlayarak (0 null nesne olarak tanımlanmış), ReadObject uygulanması arşiv içeriği durumunu korumak için bir dizi kullanabilirsiniz. Sonra ReadObject yeni nesneyi (veya sınıf tanımı) takip ettiği bilir bir PID deposundan okunduğunda, PID geçerli üst sınır m_pLoadArraybüyükse,.
Şema numaraları
Sınıf IMPLEMENT_SERIAL karşılaşıldığında sınıfına atanır, şema, sınıf uygulaması "sürümü" numarasıdır. Şema sınıfı uygulaması için başvurur, değil sayısı için belirli bir nesne (genellikle nesne sürüm olarak adlandırılır) kalıcı hale getirilmiştir.
Zama&n içinde birkaç farklı uygulamaları aynı sınıfın korumak istiyorsanız, nesnenin Serialize üye işlevi uygulama düzeltme gibi şema arttırım yükleyebilir ve implementation.nbsp eski sürümleri kullanılarak saklanan nesneler kod yazmanızı sağlayacak;
CArchive::ReadObject üye işlevi, bellekte sınıf tanımı şema sayısı farklıdır kalıcı depo şeması sayı karşılaştığında bir CArchiveException atmak olacaktır. Bu özel kurtarmak kolay değil.
Sen-ebilmek kullanma VERSIONABLE_SCHEMA ya da atılmış olan bu özel tutmak için şema sürümü. VERSIONABLE_SCHEMAkullanarak, kodunuzun uygun onun Serialize fonksiyonu CArchive::GetObjectSchema gelen bir dönüş değeri kontrol ederek önlem alabilirsiniz.
Arama sokmak doğrudan
Birçok durumda, nerede WriteObject ve ReadObject genel nesne arşiv düzeninin yükünü istenilen değildir vardır. Bu verilerin seri hale getirilirken bir CDocumentyaygın durumda. Bu durumda CDocument Serialize üye işlevi değil özü ile doğrudan denir veya operatörleri yerleştirin. Belgenin içeriğini sırayla daha genel nesne arşiv düzenini kullanabilir.
Serialize doğrudan çağırmak için de, aşağıdaki avantajları ve dezavantajları vardır:
Serialize doğrudan belgenize denir çünkü genellikle kendi ana belge başvuruları arşive belgenin nesnelerinde mümkün değildir. Bu nesneler bir işaretçi kendi Kapsayıcı belgeye açıkça verilmelidir veya geri bu işaretçileri arşivlenmeden önce CDocument işaretçiyi bir PID eşlemek için CArchive::MapObject işlevini kullanmalısınız.
Yukarıda belirtildiği gibi sizin sürüm ve sınıf bilgilerini kendinizi daha sonra yine eski dosyaları ile uyumluluk korunarak biçimini değiştirmek izin Serialize doğrudan çağırırken kodlamak. CArchive::SerializeClassRef işlevi, açıkça doğrudan bir nesne seri hale getirilirken önce ya da bir temel sınıf çağırmadan önce çağrılabilir.
Teknik notlar numarasına göre |nbsp; Teknik notlar kategorisine göre