gpt4 book ai didi

c++ - CRect 和 CRect* 如何成为 GetClientRect 的输入参数?

转载 作者:行者123 更新时间:2023-12-02 15:47:13 25 4
gpt4 key购买 nike

初学者问题。

在Win32API中,::GetClientRect的第二个参数是LPRECT,但它同时接收CRectCRect*.

我试图查看 LPRECT 是如何定义的,但它似乎只是指向结构的普通指针:

typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

CRect继承了tagRECT:

class CRect :public tagRECT {...}

使用 MFC,CWnd::GetClientRect 的工作方式相同:

CRect rect;
GetClientRect(&rect); // works
GetClientRect(rect); // works too.

这怎么可能?如果我遗漏了一些 C++ 的基本概念,请告诉我。

最佳答案

期间 overload resolution 1 编译器构建一组与参数匹配的候选函数。如果没有函数的签名与参数完全匹配,编译器将尝试应用隐式转换,每个参数最多一个。

这就是使这两种调用成为可能的原因,尽管两种情况下的隐式转换都不同:

GetClientRect(&rect);

在此函数调用表达式中,&rect 的类型为CRect*,其中CRect 公开派生自RECT,因此完成了从 CRect*RECT*(又名 LPRECT)的隐式指针转换。

GetClientRect(rect);

另一方面,此处 rect 的类型为 CRect。 C++ 不提供从 CRectRECT* 的任何内置转换,因此考虑用户定义的转换。具体来说,有一个转换运算符 CRect::operator LPRECT在给定 CRect 对象的情况下生成 RECT* 指针。

理解这两个函数调用表达式做不同的事情是至关重要的。在第二种情况下,编译器会在调用 GetClientRect() 之前注入(inject)对 operator LPRECT() 的调用。语言中没有任何内容强制转换运算符必须以任何给定方式运行,库作者需要提供合理的实现。

在这种情况下,operator LPRECT() 的行为符合预期,并且两个函数调用具有相同的可观察行为。既然您有两种方法来做同一件事,就需要指导以做出明智的选择:

虽然没有关于使用哪个选项的严格规定,但要看个人意见。我推荐 GetClientRect(&rect) 有几个原因:

  • 代码的读者更容易理解
    • 指针参数经常用作[out] 实现写入其结果的参数
    • 不那么模糊:GetClientRect(rect) 看起来 像按值传递,或者对象可能绑定(bind)到一个引用。实际上,两者都不是,而是调用了(不可见的)转换运算符
  • 不比使用转换运算符的版本贵

1 重载解析是一项核心语言功能。然而,驱动这部分语言的规则集使其成为基础。这是您最终必须学习的东西,但这是一个非常陡峭的学习曲线。 cppreference.com 链接可让您一窥所涉及的复杂性。

关于c++ - CRect 和 CRect* 如何成为 GetClientRect 的输入参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73710730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com