1. 您可以更改指针本身,使其指向另一个对象。 (
)
2. 您可以修改指向的对象。(
指针按值传递给函数,即函数获得其自己的原始指针的本地副本。这意味着您可以更改函数内部的指针参数(1),而不影响原始指针,因为只有本地副本会被修改。但是,您可以更改指向的对象(2),并且这将在函数外部可见,因为副本具有与原始指针相同的值,因此引用相同的对象。
现在来看COM的情况:
1. 接口指针(由
通过上述的机制(2)来实现这一点。
2. 使用
)的指针。
3. 如果您想知道为什么
One additional subtlety related to QueryInterface
concerns its second parameter, which is of type void **
. It is very ironic that QueryInterface
, the underpinning of the COM type system, has a fairly type-unsafe prototype in C++ [...]
IPug *pPug = 0
hr = punk->QueryInterface(IID_IPug, (void**)&pPug)
Unfortunately, the following looks equally correct to the C++ compiler:
IPug *pPug = 0
hr = punk->QueryInterface(IID_ICat, (void**)&pPug)
This more subtle variation also compiles correctly:
IPug *pPug = 0
hr = punk->QueryInterface(IID_ICat, (void**)pPug)
Given that the rules of inheritance do not apply to pointers, this alternative definition of QueryInterface
does not alleviate the problem:
HRESULT QueryInterface(REFIID riid, IUnknown** ppv);
The same limitation applies to references as to pointers as well. The following alternative definition is arguably more convenient for clients to use:
HRESULT QueryInterface(const IID& riid, void* ppv);
[...] Unfortunately, this solution does not reduce the number of errors [...] and, by eliminating the need for a cast, removes a visual indicator that C++ type safety might be in jeopardy. Given the desired semantics of QueryInterface
, the argument types Microsoft chose are reasonable, if not type safe or elegant. [...]
void **pp
只意味着 "指向void *
的指针"。 - caf