Aracılığıyla paylaş


TN002: Kalıcı nesne veri biçimi

Bu notu bir dosyada depolandığında, kalıcı C++ nesneleri ve nesne verilerin biçimini destekleyen mfc yordamları açıklar.Bu yalnızca sınıfları ile geçerlidir DECLARE_SERIAL ve IMPLEMENT_SERIAL makrolar.

Sorunu

Kalıcı veri mfc uygulaması, bir tek bitişik bölümünde bir dosya çok sayıda nesne verilerini depolar.Nesnenin Serialize yöntemi nesnenin veri compact ikili biçime çevirir.

Tüm veri kaydedildiğinde, aynı biçimde kullanarak uygulama garanti CArchive sınıfı.Kullandığı bir CArchive bir çevirmen olarak nesne.Bu nesne oluşturulan çağırdığınız kadar süre devam ederse CArchive::Close.İçeren kapsam çıkarken bu yöntem programcısı tarafından açıkça veya örtük olarak yıkıcı tarafından çağrılabilir CArchive.

Bu not uygulaması açıklar CArchive üyeleri CArchive::ReadObject ve CArchive::WriteObject.Arcobj.cpp ve ana uygulama için bu işlevler için kod bulacaksınız CArchive , Arccore.cpp.Kullanıcı kodu çağırmıyor ReadObject ve WriteObject doğrudan.Bunun yerine, bu nesneler tarafından otomatik olarak oluşturulan sınıfa özgü denkliği ekleme ve çıkarma işleçleri tarafından kullanılan DECLARE_SERIAL ve IMPLEMENT_SERIAL makrolar.Aşağıdaki kod gösterir nasıl WriteObject ve ReadObject örtülü olarak adlandırılır:

class CMyObject : public CObject
{
    DECLARE_SERIAL(CMyObject)
};

IMPLEMENT_SERIAL(CMyObj, CObject, 1)

// example usage (ar is a CArchive&)
CMyObject* pObj;
CArchive& ar;
ar << pObj;        // calls ar.WriteObject(pObj)
ar >> pObj;        // calls ar.ReadObject(RUNTIME_CLASS(CObj))

Nesneleri deposu (CArchive::WriteObject) kaydetme

Yöntem CArchive::WriteObject bir nesneyi yeniden oluşturmak için kullanılan üstbilgisi verileri yazar.Bu veriler iki bölümden oluşur: nesnenin türünü ve nesne durumu.Bu yöntem, yalnızca tek bir kopyasını işaretçiler (döngüsel işaretçiler dahil) nesne sayısı ne olursa olsun kaydedilir böylece dışarı yazılmış nesne kimliğini tutmaktan sorumludur.

(Ekleme) kaydetme ve geri yükleme (ayıklama) nesneleri çeşitli "bildirim sabitleri üzerinde." Bu, ikili biçimde depolanır ve önemli bilgileri arşivi (16-bit miktarları "w" önekini gösterir Not) değerleri şunlardır:

Tag

Description

wNullTag

null nesne işaretçisi (0) kullanılır.

wNewClassTag

Aşağıdaki sınıf tanımı bu arşiv içeriği (-1) yeni olduğunu gösterir.

wOldClassTag

Okunan nesne sınıfı için görülen bu bağlamda (0x8000) gösterir.

Nesneleri saklarken arşivini tutan bir CMapPtrToPtr ( m_pStoreMap) eşleme saklı nesne 32 bitlik kalıcı tanımlayıcı (PID) olduğu.Bir PID her benzersiz nesne ve arşiv bağlamında kaydedilen her benzersiz bir sınıf adı atanır.1'den başlayarak ardışık olarak bu PIDS dağıtılan.Bu PID'ler arşiv kapsamı dışında önemi yoktur ve özellikle de kayıt numaralarını veya diğer kimlik öğeleri ile karıştırılmamalıdır üzeresiniz.

De CArchive sınıfı, PID, 32-bit, ancak 0x7FFE ' büyük olmadıkça, 16-bit dışarı.Büyük PID'ler, 32-bit PID tarafından izlenen 0x7FFF olarak yazılır.Bu, önceki sürümlerde oluşturulmuş projeleri ile uyumluluğu korur.

(Genellikle genel ekleme işlecini kullanarak) bir arşiv nesneyi kaydetmek için bir istek yapıldığında, onay için null yapılan CObject işaretçisi.İşaretçi null, ise wNullTag arşiv akımına eklenir.

İşaretçi null ise ve seri hale getirilebilir (sınıf bir DECLARE_SERIAL sınıfı), kod denetimleri m_pStoreMap nesne zaten kaydedilmiş olup olmadığını görmek için.Varsa, arşiv akımına o nesneyle ilişkilendirilmiş 32-bit PID kodunu ekler.

Nesne önceden kaydedilmiş değil, göz önünde bulundurulması gereken iki olasılık vardır: nesne ve nesne tam türü (sınıf) bu arşiv içeriği yeni veya önceden tam bir tür nesnesidir.Tür görmediğini, belirlemek için kod sorguları m_pStoreMap için bir CRuntimeClass eşleşen nesne CRuntimeClass kaydedilmesini nesnesiyle ilişkili nesne.Bir eşleşme varsa WriteObject arasındaki bit temelinde etiket ekler OR , wOldClassTag ve bu dizin.CRuntimeClass Bu arşiv içeriği için yeni WriteObject o sınıfın yeni bir PID atar ve koyarak arşivin ekler wNewClassTag değeri.

Bu sınıf tanımlayıcısı kullanılarak arşiv içine sonra eklenen CRuntimeClass::Store yöntemi.CRuntimeClass::StoreŞema sınıfı (aşağıya bakın) sayısı ve sınıf ASCII metin adını ekler.Not ASCII metin adı kullanımı, uygulamalar arasında arşiv benzersizliğini garantilemez.Bu nedenle, veri dosyalarınızı bozulmasını önlemek için etiketleyin.Sınıf bilgisi ekleme noktasını arşiv nesnesine geçirir m_pStoreMap ve sonra Serialize yöntemi sınıfa özgü verileri eklemek için.Nesnenin içine yerleştirerek m_pStoreMap önce arama Serialize nesnenin birden fazla kopyasını deposuna kaydedildi engeller.

İlk arayan (genellikle ağ nesnelerinin kökü) döndürürken çağırması gerekir CArchive::Close.Diğer yapmayı planlıyorsanız CFileişlemleri çağırmanız gerekir CArchive yöntemi Temizleme arşiv bozulmasını önlemek için.

[!NOT]

Bu uygulama 0x3FFFFFFE indisler arşiv içeriği başına sabit bir sınır getirir.Bu sayı benzersiz nesneler ve tek bir Arşivde kayıtlı sınıflar maksimum sayısını temsil eder ancak tek disk dosya sınırsız sayıda arşiv içerikler olabilir.

Nesneleri deposu (CArchive::ReadObject) yükleniyor

Nesneleri kullanır (ayıklama) yükleme CArchive::ReadObject yöntemi ve converse, WriteObject.Olduğu gibi WriteObject, ReadObject doğrudan kullanıcı kodu tarafından; denir. Kullanıcı kodu çağıran tür-güvenli çıkarma işlecini çağırmak ReadObject beklenen ile CRuntimeClass.Bu ayıklama işlemi türü bütünlüğünü insures.

Bu yana WriteObject uygulaması atanan 1'den başlayarak artan PID (0 öntanımlı null nesne), ReadObject uygulaması arşiv içeriği durumunu korumak için bir dizi kullanabilirsiniz.Ne zaman bir PID okuma deposundan PID geçerli üst sınır büyükse, m_pLoadArray, ReadObject yeni bir nesne (veya sınıf tanımı) izleyen bilir.

Şema numaraları

Sınıf için atanan şema numarasını, IMPLEMENT_SERIAL sınıfının yöntem karşılaşıldığında, sınıf uygulaması "sürümü".Şema sınıfı için olmasýndan, değil sayısı için belirli bir nesne (genellikle nesne sürüm olarak da adlandırılır) kalıcı yapıldı.

Şema nesne 's gözden geçirme gibi birkaç farklı uygulamaları aynı sınıfın zamanla korumak istiyorsanız, artan Serialize yöntemini uygulama yükleyebilir ve uygulama eski sürümleri kullanılarak saklanan nesneler kod yazmanızı etkinleştirmek.

CArchive::ReadObject Yöntemi durum bir CArchiveException sınıf tanımı bellekteki şema sayısı farklıdır kalıcı depo şeması sayı bulduğu zaman.Bu bir istisna kurtarmak kolay değildir.

Kullanabileceğiniz VERSIONABLE_SCHEMA birlikte (bitwise OR) tarafından atılan bu özel tutmak için şema sürümü.Kullanarak VERSIONABLE_SCHEMA, kodunuzu uygun eylemi gerçekleştirin kendi Serialize gelen bir dönüş değeri denetleyerek işlev CArchive::GetObjectSchema.

Arama doğrudan seri hale

Genel nesne arşiv düzeninin yükü çoğu durumlarda WriteObject ve ReadObject gerekli değildir.Bu verileri seri hale getirilirken, ortak olduğu bir CDocument.Bu durumda, Serialize yöntemi CDocument değil extract ya da Ekle işleci ile doğrudan denir.Belgenin içeriğini de daha genel nesne arşiv düzenini kullanabilir.

Arayan Serialize doğrudan aşağıdaki avantajları ve dezavantajları vardır:

  • Fazladan bir bayt arşivi önce veya sonra nesne seri hale getirilmiş eklenir.Bu yalnızca kaydedilen verileri küçültür ancak uygulamak sağlar Serialize herhangi bir işleme yordamları dosya formatları.

  • mfc ayarlanmış şekilde WriteObject ve ReadObject uygulamaları ve ilgili Koleksiyonlar bağlanmamış uygulamanıza daha genel nesne arşiv düzeninin başka bir amaç için gerekli olmadıkça.

  • Kodunuzu, eski şema numaralardan kurtarmak yok.Bu belge seri hale getirme kodu kodlama şeması sayılar, dosya biçimi sürüm numaraları ya da ne olursa olsun tanımlama numaraları sorumlu kılar veri dosyalarınızı başlangıcında kullanın.

  • Doğrudan bir çağrı ile sıralanmış herhangi bir nesne Serialize değil kullanmanız gerekir CArchive::GetObjectSchema veya gerekir tutamacı (UINT) -1 dönüş değeri gösteren sürümü bilinmiyor.

Çünkü Serialize olarak adlandırılan doğrudan belgenize, genellikle kendi ana belge başvurularını arşivlemek için belgenin nesnelerinde mümkündür değildir.Bu nesneler bir işaretçi kendi kapsayıcı belge açıkça verilmelidir veya kullanmanız gerekir CArchive::MapObject eşlemek için işlev CDocument geri bu işaretçileri arşivlenmeden önce PID için işaretçi.

Daha önce belirtildiði gibi sürüm kodlamak ve aradığınızda, kendinizi sınıf bilgisi Serialize , doğrudan, daha sonra yine eski dosyaları ile uyumluluk koruyarak biçimini etkinleştirme.CArchive::SerializeClass İşlevi adlı açıkça bir temel sınıf çağırmadan önce ya da önce doğrudan bir nesne seri hale getirilmedi.

Ayrıca bkz.

Diğer Kaynaklar

Teknik notlar numarasına göre

Kategoriye göre teknik notlar