Bu notu birden çok devralma (mı) ile Microsoft Foundation Classes açıklar.
Neden birden çok devralma?
MI değeri nesne yönelimli topluluklar ve C++'ta devam eden bir tartışma yoktur. Visual c++ derleyici ve geliştirme ortamı tam olarak mı destekler.
Mfc kullanmak mı anlamak gerekmez böylece mfc sınıf kitaplığı tasarlanmıştır. MI mfc sınıfların birinde kullanılmaz. Biz-si olmak kurmak mı bir synyf kitaply?y yazmak için gerekli değildir, ne ciddi uygulamalar yazmak için gereklidir. Biz bu kararı terk MI kullanacak biçimde kişisel bir karar olabilir.
Eğer kullanmak mı istediğiniz?
Eğer sen zaten nasıl mı kullanmak, performansı ticaret-off anlamak ve mfc kullanmak istediğiniz anlamak, bu technote ne yapması gerektiğini size söyleyecektir. Bazı kısıtlamalar genel c++ kısıtlamaları vardır, diğerleri mfc mimari empoze.
Nasıl ortak mfc deyim kullanımını etkiler MI, teknik konulardan bazıları aşağıda açıklanmıştır. Bu teknik not dahil edildiği mı kullanarak tam bir mfc uygulaması sonunda derlemek ve ayıklamak.
CRuntimeClass
Kalıcılık ve dinamik nesne oluşturma mekanizmaları mfc CRuntimeClass veri yapısı sınıfları benzersiz olarak tanımlamak için kullanın. mfc uygulaması dinamik ve/veya seri hale getirilebilir her sınıfta bu tür bir yapı ilişkilendirir. Bu yapılar, uygulamanın başlangıç sırasında özel bir statik nesne türü AFX_CLASSINITkullanarak başlatılır. mfc revizyonlar arasında değişme olasılığı olduğu gibi kendinizi bu bilgilerin uygulanması ile endişe değil.
CRuntimeClass geçerli uygulama, birden çok devralma runtime türü bilgileri desteklemez. Bu mfc uygulamanızda mı kullanamazsınız, ancak bunu yaparsanız, daha fazla bir temel sınıfı olan nesneleriyle çalışırken belirli sorumlulukları olacak demek değildir.
Birden fazla temel sınıflar varsa CObject::IsKindOf üye işlev nesne türünü doğru belirlemez. Bu nedenle, sanal bir temel sınıf olarak CObject kullanamaz ve tüm aramalar için CObject üye işlevler Serialize ve Yeni operatör gibi bu c++ uygun işlev çağrısı disambiguate böylece kapsam Elemeleri olması gerekmektedir. mfc içinde MI gerek bulursanız, sonra CObject temel sınıf temel sınıflar listesinde en soldaki sınıfını içeren sınıf emin olmalıdır.
Kullanım ve ihlalleri mı üzerinde daha fazla tavsiye için bkz: c++ programlama stiller gelişmiş ve deyim tarafından James o. Coplien (Addison Wesley, 1992).
CObject - tüm sınıflar kök
Bildiğiniz gibi tüm önemli sınıflarını doğrudan ya da dolaylı olarak CObjectsınıfından türer. CObject herhangi bir üye veri yok, ama bazı varsayılan işlevselliğe sahiptir. MI kullanırken, iki ya da daha fazla CObjectdevralan ortak olacak-türetilmiş sınıfları, örneğin, bir CFrameWnd ve bir CObList:
cListWnd sınıfı: kamu CFrameWnd, kamu CObList
{
...
};
CListWnd myListWnd
Bu durumda CObject birlikte iki kez, hangi neden iki sorunları:
myListW&nd.Dump(afxDump);
nbsp; / / derleme zamanı hatası, CFrameWnd::Dump veya CObList::Dump
Önerilen adımlar
Ne zaman iki veya daha fazla CObject ile yeni bir sınıf oluşturmak temel sınıflar türetilmiş, bu CObject üye kişilerin kullanmasını beklediğiniz reimplement. Operatörler Yeni ve silmek zorunludur, döküm önerilir. Örneğin:
cListWnd sınıfı: kamu CFrameWnd, kamu CObList
{
public:
nbsp; void * operatör yeni (size_t nSize)
{CFrameWnd::operator new(nSize) return;}
void operator delete (void * p)
{CFrameWnd::operator delete(p);}
void dökümü (CDumpContent & dc)
{CFrameWnd::Dump(dc);
CObList::Dump(dc); }
...
}
CObject sanal miras?
"CObject neredeyse devralan, isteyebilir, Bütün belirsizlik sorunları won't go away?".
Daha verimli Microsoft nesne modelinde, sanal devralma (yalnızca birden çok devralma belirli durumlarda tek miras olabildiğince verimli değildir gibi) sanal olmayan miras etkin değildir. CObjectüye veri olduğundan, sanal devralma temel sınıf üyesi verilerin çoklu kopyalarının önlemek için gerekli değildir.
Gerçek cevap yok, sanal miras değil yukarıda gösterildiği belirsizlik sorunları çözmek. Örneğin: ( CFrameWnd ve CObList farklı uygulamadan yana) dökümü sanal üye işlev hala belirsiz.
Yukarıdaki adımları anlam sağlamak bu nedenle öneririz:
CObject::IsKindOf ve yazarak çalıştırma
CObject mfc tarafından desteklenen çalışma yazarak mekanizması, makroları DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC, declare_dyncreate, IMPLEMENT_DYNCREATE, DECLARE_SERIAL ve IMPLEMENT_SERIALkullanır. Bu güvenli döküm listeleri için izin veren bir çalışma zamanı tür kontrol olanağı vermek.
Bu makrolar yalnızca tek bir temel sınıf desteği ve çarpma devralınan sınıfları için sınırlı bir şekilde çalışacaktır. IMPLEMENT_DYNAMIC veya IMPLEMENT_SERIAL temel sınıfın ilk (veya en soldaki) temel sınıfı olmalıdır. Örneğin,
cListWnd sınıfı: kamu CFrameWnd, kamu CObList
{
nbsp; DECLARE_DY&NAMIC(CListWnd)
...
};
IMPLEMENT_DYNAMIC (CListWnd, CFrameWnd)
Bu tür en soldaki için temel sınıf yalnızca denetimi sağlayacak. Çalışma Zamanı tür sistemi ilave üsler (CObList bu durumda) hakkında hiçbir şey bilmek.
CWnd ve ileti haritalar
Mfc ileti göster sistemin düzgün çalışması sırayla iki ek gereksinimler vardır:
Yukarıdaki örnekte, CFrameWnd ilk temel sınıftır.
İşe yaramaz bazı örnekler:
cTwoWi&ndows sınıfı: kamu CFrameWnd, ortak CEdit
nbsp; { ... };
/ / Hata: CWnd iki kopyası
CListEdit sınıfı: kamu CObList, ortak CEdit
{ ... };
/ / Hata: CEdit (CWnd türetilmiş) ilk olmalıdır
Bir örnek Program mı kullanma
Aşağıdaki örnek, tek bir sınıf CFrameWnd ve CWinApp' den oluşan bağımsız bir uygulamadır. Bir uygulama yapılandırma bu şekilde bir önerilen değildir, ama bu küçük mfc uygulaması ile bir sınıfın örneği.
Aşağıdaki programı kesebilir ve kopya o-e doğru helloapp üzerine.cpp tek-devralma mfc Genel örnek helloapp. Sonra program normalde yaptığınız gibi oluşturun.
#include <afxwin.h>
class CHelloAppAndFrame : public CFrameWnd, public CWinApp
{
public:
CHelloAppAndFrame()
{ }
// Necessary evil for MI disambiguity
void* operator new(size_t nSize)
{ return CFrameWnd::operator new(nSize); }
void operator delete(void* p)
{ CFrameWnd::operator delete(p); }
// Implementation
// CWinApp overrides
virtual BOOL InitInstance();
// CFrameWnd overrides
virtual void PostNcDestroy();
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CHelloAppAndFrame, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// since the frame window is not allocated on the heap, we must
// override PostNCDestroy not to delete the frame object
void CHelloAppAndFrame::PostNcDestroy()
{
// do nothing (do not call base class)
}
void CHelloAppAndFrame::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
CString s = "Hello, Windows!";
dc.SetTextAlign(TA_BASELINE | TA_CENTER);
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkMode(TRANSPARENT);
dc.TextOut(rect.right / 2, rect.bottom / 2, s);
}
// Application initialization
BOOL CHelloAppAndFrame::InitInstance()
{
// first create the main frame
if (!CFrameWnd::Create(NULL, "Multiple Inheritance Sample",
WS_OVERLAPPEDWINDOW, rectDefault))
return FALSE;
// the application object is also a frame window
m_pMainWnd = this;
ShowWindow(m_nCmdShow);
return TRUE;
}
CHelloAppAndFrame theHelloAppAndFrame;
Teknik notlar numarasına göre |nbsp; Teknik notlar kategorisine göre