这真的是得到正确的地址的实例函数的唯一方法:有没有更好的方法来选择正确的方法重载?
typedef CBitmap * (CDC::* SelectObjectBitmap)(CBitmap*);
SelectObjectBitmap pmf = (SelectObjectBitmap)&CDC::SelectObject;
首先,一个有能力创造一个typedef,然后一个人用它来强制编译器选择正确的重载方法时采取其地址?
有没有语法,更自然,自成一体,如:
SelecdtObjectBitmap pmf = &CDC::SelectObject(CBitmap*);
我在代码中使用ScopeGuard频繁。一个明显的用途是确保任何临时CDC对象首先被选中到给定的DC中,然后在范围退出时将其删除,使得我的代码即使在特殊情况下也是免费的 - 并且同时清理写入的代码(愚蠢的多个退出路径并尝试/ catch等尝试处理从给定的CDC中删除任何选定的对象)。
那么什么目前我被迫做一个更完整的例子看起来像:
// 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);
它总是让我吃惊得如同地狱愚蠢的,我需要的typedef每个重载函数,我想借此地址。
那么...有没有更好的办法?
编辑:基于人已经提供了答案,我相信我有一个解决方案,我根本需要:即有MakeGuard更自然的语法,推导出正确的选择对象覆盖了我:
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));
}
这让我上面的代码更改为:
ScopeGuard guard_canvas = MakeSelectObjectGuard(memdc, &canvas);
///////////////////////////////// /////////////////////////
对于那些谁可以看看这里的非MFC版本的同一件事:
//////////////////////////////////////////////////////////////////////////
//
// 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;
};
//////////////////////// //////////////////////////////////
谢谢回复的所有人&评论! :D
你可以做到这一点,但它肯定不会很漂亮 - 你基本上最终会在当前使用typedef名称的地方插入typedef的主体。 – James 2010-01-14 16:11:43
希望它不是这个CBitmap:http://thedailywtf.com/Articles/The-cbitmap.aspx – 2010-01-14 18:14:54