RefPtr 编辑

RefPtr (formerly known as nsRefPtr, see bug 1207245) is a general class to implement reference counting pointers for objects. It is similar to nsCOMPtr, but does not require that the type be an XPCOM interface.  Like with nsCOMPtr, it is the responsibility of the object itself to implement reference counting. This is done using the functions AddRef() and Release(), which respectively modify a variable of type nsAutoRefCnt, which basically is a wrapper around a count of the number of references refering to the class.

When should I use nsCOMPtr versus RefPtr?

The rules are simple: use nsCOMPtr to hold pointers to XPCOM interfaces, and use RefPtr to hold pointers to concrete class, even if the concrete class implements one or more XPCOM interfaces.

So for XPCOM interfaces:

nsCOMPtr<nsISupports> a;

nsCOMPtr<nsIFoo> foo;

And for concrete classes:

RefPtr<nsFoo> foo;  // class that implements nsIFoo;

RefPtr<Bar> bar;    // some random class that I want ref-counted but has nothing to do with XPCOM:
                    // Just implement AddRef() and Release() and it will work with RefPtr

It is important that nsCOMPtr is not used to hold a pointer to a concrete class since this can cause compile time errors or runtime errors. Bug 756640 is on file to enforce this rule but hasn't yet been fixed.

While RefPtr should not generally be used to hold a pointer to an XPCOM interface, this is flexible. There are no technical problems with doing so, and in some cases it may be necessary (see bug 756640 comment 1). For example, we have template classes such as OwningNullPtr that can contain a RefPtr to an XPCOM interface.

XXX It's not clear that the details in the following paragraph are correct. It was derived from an old #developers discussion. It's unclear to me when the compiler will reject an attempt to use nsCOMPtr to hold a concrete class pointer and when it will not (will it only rejecte it if a QI is involved in the construction or or assignment to the nsCOMPtr (common in implementation details of nsCOMPtr) but not when an instance of the concrete class is assigned directly?). And it's not clear what happens when the compiler does accept this pattern. What goes wrong at runtime - UAF? memory leak? QI failure and null-deref crashes?.

Note: in the above example, "nsCOMPtr<nsFoo>" might compile and work OK (it won't if your XPCOM class multiply-inherits nsISupports).   But this is considered Bad Form, and may soon be made a compile-time error.  Don't do it!

Can I QueryInterface a RefPtr to get a nsCOMPtr from the object it points to?

Sure.  Instead of using "do_QueryInterface()" (which is used for nsCOMPtrs), use "do_QueryObject()", which works with RefPtrs:

// Let's say nsFoo implements nsIFoo and nsIBar XPCOM interfaces:
RefPtr<nsFoo> foo = new nsFoo();
nsCOMPtr<nsIBar> bar(do_QueryObject(foo));
MOZ_ASSERT(bar, "Yikes someone changed the base classes of nsFoo");

Can I QueryInterface an nsCOMPtr back to a RefPtr?

Yes. If the concrete class has its own XPCOM IID (not true by default, but one can be added), you can also QI from an XPCOM pointer to a concrete type:

bar = do_QueryObject(foo);
if (bar) { ... }

See this post for more details.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:27 次

字数:4132

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文