nsCOMPtr versus RefPtr 编辑
Gecko code uses both nsCOMPtr
and RefPtr
as smart pointers. This guide provides some explanation and advice on how to choose between them.
General Rule of Thumb for nsCOMPtr versus RefPtr
The general rule of thumb is to use nsCOMPtr<T>
when T
is an interface type, and RefPtr<T>
when T
is a concrete type.
This basic rule derives from the fact that some of the nsCOMPtr<T>
code is factored into the nsCOMPtr_base
base class, which stores the underlying mRawPtr
as an nsISupports*
. (although, confusingly, debug builds don't work this way). This design saves some space in the binary (or at least it used to). Since nsCOMPtr
stores the pointer as an nsISupports*
, it must be possible to unambiguously cast from T*
to nsISupports*
. Many concrete classes inherit from nsISupports
in more than one way, so they cannot be unambiguously cast to nsISupports*
. Thus, these concrete classes cannot be used with nsCOMPtr
.
While is possible to use nsCOMPtr<T>
on concrete classes T
that only singly inherit from nsISupports
, it is best to avoid doing so. In the future, more base classes might be added to T
that would then cause unrelated code to break, which would be very confusing. Hence, the interface versus concrete class rule of thumb: interfaces will never multiply inherit from nsISupports
, so they can always use be used with nsCOMPtr
without fear of breaking in the future. Concrete classes should only be used with RefPtr
.
nsCOMPtr<T>
also requires that you can QueryInterface
to type T
. It does this so that it can assert that mRawPtr
is a canonical T
pointer (i.e., that mRawPtr->QueryInterface(T_IID) == mRawPtr
).
do_QueryInterface versus do_QueryObject
The do_QueryInterface
helper is only available when assigning to nsCOMPtr
. It also requires that the argument singly inherit from nsISupports
(since the type of the argument is nsISupports*
). For other cases, there is do_QueryObject
, which is essentially a more powerful form of do_QueryInterface
. It differs from do_QueryInterface
as follows:
do_QueryObject
inherits fromnsCOMPtr_helper
, so it can be assigned into bothnsCOMPtr
andRefPtr
. The downside of this inheritance is thatdo_QueryObject
requires an extra virtual call tooperator()
in the helper method.do_QueryObject
is templated on the argument type, so it's possible to pass in objects that multiply inherit fromnsISupports
. However, when the destination type is an XPCOM interface, it's probably better tostatic_cast
to a class that unambiguously inherits fromnsISupports
and usedo_QueryInterface
in such cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论