初學者問題。
在 Win32API 中,第二個引數::GetClientRect
是LPRECT
,但它同時接收CRect
和CRect*
。
我試圖看看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 的一些基本概念,請告訴我。
uj5u.com熱心網友回復:
在多載決議1期間,編譯器構建一組與引數匹配的候選函式。如果沒有一個函式的簽名與引數完全匹配,那么編譯器將嘗試應用隱式轉換,每個引數最多一個。
這就是使這兩個呼叫成為可能的原因,盡管在任何一種情況下隱式轉換都不同:
GetClientRect(&rect);
在這個函式呼叫運算式中,&rect
具有型別CRect*
,CRect
公開派生自,因此完成了從to (aka )RECT
的隱式指標轉換。CRect*
RECT*
LPRECT
GetClientRect(rect);
另一方面,這里rect
有 type CRect
。CRect
C 不提供從to的任何內置轉換RECT*
,因此考慮了用戶定義的轉換。具體來說,有一個轉換運算子CRect::operator LPRECT
可以生成RECT*
給定CRect
物件的指標。
理解這兩個函式呼叫運算式做不同的事情是至關重要的。在第二種情況下,編譯器會operator LPRECT()
在呼叫GetClientRect()
. 語言中沒有任何內容要求轉換運算子必須以任何給定的方式運行,并且由庫作者提供合理的實作。
在這種情況下,operator LPRECT()
行為與預期的一樣,并且兩個函式呼叫具有相同的可觀察行為。既然您有兩種方法可以做同樣的事情,那么需要指導才能做出明智的選擇:
雖然對于使用哪些選項沒有嚴格的規定,但這取決于意見。我會推薦GetClientRect(&rect)
幾個原因:
- 代碼讀者更容易理解
- 指標引數經常用作
[out]
實作寫入結果的引數 - 不那么模棱兩可:
GetClientRect(rect)
看起來像按值傳遞,或者物件可能系結到一個參考。實際上,兩者都不是,而是呼叫(不可見的)轉換運算子
- 指標引數經常用作
- 不比使用轉換運算子的版本貴
1 多載決議是一個核心語言特性。然而,驅動這部分語言的一組規則使它不是基本的。這是你最終必須學習的東西,但這是一個非常陡峭的學習曲線。cppreference.com鏈接讓您了解所涉及的復雜性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/508423.html
上一篇:如何使用在python中回傳二維陣列(矩陣)的C函式(并進行一些計算機繁重的計算)從python復制二維陣列(矩陣)?