Ist das wirklich der einzige Weg, die richtige Adresse für eine Instanz Funktion zu erhalten:gibt es eine bessere Möglichkeit, die richtige Methodenüberladung auszuwählen?
typedef CBitmap * (CDC::* SelectObjectBitmap)(CBitmap*);
SelectObjectBitmap pmf = (SelectObjectBitmap)&CDC::SelectObject;
Zuerst hat man einen typedef zu erstellen, und dann hat man das verwenden, um die Compiler zu zwingen, die richtigen überlastete zu wählen Methode, wenn man seine Adresse nimmt?
Gibt es keine Syntax, die mehr natürlich ist, und in sich geschlossene, wie zum Beispiel:
SelecdtObjectBitmap pmf = &CDC::SelectObject(CBitmap*);
ich ScopeGuard oft in meinem Code verwenden. Und eine naheliegende Verwendung besteht darin, sicherzustellen, dass alle temporären CDC-Objekte zuerst in einem bestimmten DC ausgewählt und dann beim Exit entfernt werden, so dass mein Code auch unter außergewöhnlichen Umständen frei wird - und gleichzeitig den geschriebenen Code aufräumt (dumme mehrfache Exit-Pfade)/catch und so weiter, um zu versuchen, ausgewählte Objekte von einem bestimmten CDC zu entfernen).
So ein vollständigeres Beispiel dafür, was ich zur Zeit gezwungen bin, sieht zu tun:
// get our client rect
CRect rcClient;
GetClientRect(rcClient);
// get the real DC we're drawing on
PAINTSTRUCT ps;
CDC * pDrawContext = BeginPaint(&ps);
// create a drawing buffer
CBitmap canvas;
canvas.CreateCompatibleBitmap(pDrawContext, rcClient.Width(), rcClient.Height());
CDC memdc;
memdc.CreateCompatibleDC(pDrawContext);
//*** HERE'S THE LINE THAT REALLY USES THE TYPEDEF WHICH i WISH TO ELIMINATE ***//
ScopeGuard guard_canvas = MakeObjGuard(memdc, (SelectObjectBitmap)&CDC::SelectObject, memdc.SelectObject(&canvas));
// copy the image to screen
pDrawContext->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &memdc, rcClient.left, rcClient.top, SRCCOPY);
// display updated
EndPaint(&ps);
Es hat mich immer geschlagen wie doof wie die Hölle, die ich jede überladene Funktion typedef muß, die ich wünschte, das nehmen Adresse von.
Also ... gibt es einen besseren Weg ?!
EDIT: Basierend auf den Antworten Leute geliefert haben, ich glaube, ich eine Lösung für mein zugrunde liegende Bedürfnis haben: dh eine natürlichere Syntax für MakeGuard zu haben, die für mich die richtige AuswählenObjekt Überschreibung folgert:
template <class GDIObj>
ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*> MakeSelectObjectGuard(CDC & dc, GDIObj * pGDIObj)
{
return ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*>::MakeObjGuard(dc, (GDIObj*(CDC::*)(GDIObj*))&CDC::SelectObject, dc.SelectObject(pGDIObj));
}
Welche meiner obigen Codeänderung macht:
ScopeGuard guard_canvas = MakeSelectObjectGuard(memdc, &canvas);
///////////////////////////////// ///////////////////////////
Für diejenigen, die hier für eine nicht-MFC-Version der gleichen Sache aussehen könnte:
//////////////////////////////////////////////////////////////////////////
//
// AutoSelectGDIObject
// selects a given HGDIOBJ into a given HDC,
// and automatically reverses the operation at scope exit
//
// AKA:
// "Tired of tripping over the same stupid code year after year"
//
// Example 1:
// CFont f;
// f.CreateIndirect(&lf);
// AutoSelectGDIObject select_font(*pDC, f);
//
// Example 2:
// HFONT hf = ::CreateFontIndirect(&lf);
// AutoSelectGDIObject select_font(hdc, hf);
//
// NOTE:
// Do NOT use this with an HREGION. Those don't need to be swapped with what's in the DC.
//////////////////////////////////////////////////////////////////////////
class AutoSelectGDIObject
{
public:
AutoSelectGDIObject(HDC hdc, HGDIOBJ gdiobj)
: m_hdc(hdc)
, m_gdiobj(gdiobj)
, m_oldobj(::SelectObject(m_hdc, gdiobj))
{
ASSERT(m_oldobj != m_gdiobj);
}
~AutoSelectGDIObject()
{
VERIFY(m_gdiobj == ::SelectObject(m_hdc, m_oldobj));
}
private:
const HDC m_hdc;
const HGDIOBJ m_gdiobj;
const HGDIOBJ m_oldobj;
};
//////////////////////// //////////////////////////////////
Dank Jeder, antwortete & kommentiert! : D
Sie können es tun, aber es wird sicherlich nicht hübsch sein - Sie werden im Grunde den Körper des Typedef einfügen, wo Sie derzeit den Typedef-Namen verwenden. – James
Hoffe, es ist nicht diese CBitmap: http://thedailywtf.com/Articles/The-cbitmap.aspx –