首先确定这是一个重载。就好比int a = 5; 凭什么 = 就能直接用。c语言也许想当然,但是到java中你就会明白 = 其实是重载了的。再比如 char c = 65;这其实都是编译器做好了转换。如果不做转换,编译都不能通过。
返回的LPRECT很简单,也许CRect里面有个成员变量RECT rc,那么重载函数返回 &rc 就行了。
它重载了LPRECT。直接看MFC的源码。判断参数类型时,发现CRect中有LPRECT类型转换操作符,就会调这个操作符重载函数。
代码(atltypes.h):
class CRect : public tagRECT
{
....
// convert between CRect and LPRECT/LPCRECT (no need for &)
operator LPRECT() throw();
operator LPCRECT() const throw();
};
代码:atltypes.inl
ATLTYPES_INLINE CRect::operator LPRECT() throw()
{
return this;
}
ATLTYPES_INLINE CRect::operator LPCRECT() const throw()
{
return this;
}
CRect确实重载了LPRECT操作,并且可以直接将CRect作为LPRECT类型的参数带入。
其实CRect重载的LPRECT操作非常简单,函数中就是一句:return this;
this是对象自身的指针,为什么返回自身就可以获得LPRECT呢,这里看下面两段代码:
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
class CRect : public tagRECT
{
//略...
};
第一段代码说明,LPRECT就是RECT结构体指针
第二段代码说明,CRect类的基类就是RECT结构体!
根据C++的类重载和继承原则,子类的指针转换为父类指针是没有问题的,因此CRect的this可以成为RECT的结构体指针,这才是LPRECT操作的真是面目!
确实是重载了LPRECT。直接看MFC的源码。判断参数类型时,发现CRect中有LPRECT类型转换操作符,就会调这个操作符重载函数。
atltypes.h中的:
class CRect : public tagRECT
{
....
// convert between CRect and LPRECT/LPCRECT (no need for &)
operator LPRECT() throw();
operator LPCRECT() const throw();
};
atltypes.inl中的:
ATLTYPES_INLINE CRect::operator LPRECT() throw()
{
return this;
}
ATLTYPES_INLINE CRect::operator LPCRECT() const throw()
{
return this;
}