为何CRect与CRect*均可作为GetClientRect的输入参数?
Win32API与MFC中GetClientRect参数的实现原理
一、Win32API的::GetClientRect接收CRect*的原因
你看到的LPRECT本质是tagRECT*的别名,而CRect是public继承自tagRECT的。在C++中,指向派生类的指针可以隐式转换为指向基类的指针——因为CRect的内存布局开头部分和tagRECT完全一致,所以CRect*可以自动转换成LPRECT,这就是传&rect(CRect*)能被::GetClientRect接受的核心原因。
二、MFC的CWnd::GetClientRect接收CRect对象的原因
这是MFC为了简化开发做的函数重载。CWnd::GetClientRect除了有和Win32API一致的、接受LPRECT参数的版本外,还额外提供了一个接受CRect&(引用)的重载,大致实现如下:
void CWnd::GetClientRect(CRect& rect) const { ::GetClientRect(m_hWnd, &rect); }
当你直接传rect(CRect对象)时,会匹配这个引用参数的重载,函数内部自动取对象的地址传给Win32API的::GetClientRect,所以看起来像是直接传对象也能生效。
补充说明
需要注意:直接把CRect对象传给Win32原生的::GetClientRect是不行的,因为它只接受指针类型参数;只有MFC封装的版本才通过重载实现了传对象的便捷写法。
内容的提问来源于stack exchange,提问作者starriet 차주녕
相关产品推荐
相关产品推荐

