在看MFC源码的过程中,有个地方一直不解,看如下代码
BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT&
rect,
CWnd*
pParentWnd,
LPCTSTR lpszMenuName,
DWORD dwExStyle,
CCreateContext*
pContext)
{
HMENU hMenu =
NULL;
if (lpszMenuName !=
NULL)
{
// load in a menu that will get destroyed when window gets destroyed
HINSTANCE hInst =
AfxFindResourceHandle(lpszMenuName, ATL_RT_MENU);
if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) ==
NULL)
{
TRACE(traceAppMsg, 0,
"Warning: failed to load menu for CFrameWnd.\n");
PostNcDestroy(); // perhaps delete the C++ object
return FALSE;
}
}
m_strTitle = lpszWindowName;
// save title for later
if (!
CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom -
rect.top,
pParentWnd->
GetSafeHwnd(), hMenu, (LPVOID)pContext))
{
TRACE(traceAppMsg, 0,
"Warning: failed to create CFrameWnd.\n");
if (hMenu !=
NULL)
DestroyMenu(hMenu);
return FALSE;
}
return TRUE;
}
注意Create函数参数pParentWnd如果传NULL进来,pParentWnd->GetSafeHwnd并不会报错。开始一看,吓我一大跳,怎么不出现内存访问违规呢,奇怪了。经过试验,还是自己的知识太欠缺了啊。
原因还得在代码中找,看下GetSafeHwnd的实现, 内部判断了this==NULL(第一次知道还可以这样用)
_AFXWIN_INLINE HWND CWnd::GetSafeHwnd()
const
{ return this == NULL ? NULL : m_hWnd; }
以下是试验代码:
#include <iostream>
using namespace std;
class TestClass
{
public:
TestClass():m_nInt( 222 )
{
cout <<
"TestClass()" <<
endl;
}
virtual ~
TestClass()
{
cout <<
"~TestClass()" <<
endl;
}
//this==NULL时,未使用本类变量
int GetInt()
{
if (
this ==
NULL )
{
return 888;
}
return m_nInt;
}
//函数引用此类变量
int GetInt2()
{
return m_nInt;
}
private:
int m_nInt;
};
int main()
{
TestClass* pTest =
NULL;
//this==NULL时,未使用本类变量,故可正常调用
int nRet = pTest->
GetInt();
//this==NULL时,使用本类变量,
//而对象并不存在,内存访问违规!!!
int nRet2 = pTest->
GetInt2();
return 0;
}
TODO: 有空要学习下《深度探索C++对象模型》
转载请注明原文地址: https://ju.6miu.com/read-25061.html