std :: shared_ptr <Type>和Type ^之间的区别

pso*_*usa 1 c++ c++11 windows-runtime c++-cx

我真的不明白在C++/CX中shared_ptr和新句柄符号(^)之间的区别.根据我的阅读,他们似乎在引用计数和内存管理方面做同样的事情.我错过了什么?

std::shared_ptr<Type>
//vs
Type^
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 12

仅考虑终身管理,这些是相同的:a shared_ptr<T>拥有对象的强大(拥有)引用T; a T^做同样的事. make_shared<T>大致相当于ref new TC++/CX.

如果到处都有你T^认为shared_ptr<T>或者ComPtr<T>CComPtr<T>那么,那就没关系 - 终身管理大致相同.

但是,生命周期管理的工作原理是不同的:每种T类型T^都是格式良好的Windows运行时引用类型实现了IUnknown接口,因此T对象在内部引用计数(*). shared_ptr<T>支持任意类型并使用外部引用计数(即,它分配自己的引用计数机制来控制对象的生命周期).

对于弱引用,shared_ptr<T>has weak_ptr<T>T^has WeakReference. WeakReference不是强类型的,但您可以轻松地在其周围编写强类型的引用包装.否则,弱引用会像您期望的那样工作.对弱引用的支持是可选的:并非所有引用类型都支持弱引用,但大多数都支持弱引用.

(*)有一个例外: Platform::String^,它不是Windows运行时引用类型,但由于各种原因而特别处理.但是,您可以将其视为T^与终身管理相关的任何其他内容.


那么,为什么Windows运行时类型在C++/CX中戴帽子呢?为什么不使用shared_ptr<T>ComPtr<T>使用库解决方案?

这是因为你从来没有真正拥有指向具体运行时类型的指针(或帽子):你只能通过指向其类型实现的接口之一的指针与对象进行交互.Windows运行时也不支持接口或类继承:每个接口必须直接派生IInspectable,并且通过使用COM聚合来模拟类继承.

简而言之,没有库解决方案可以产生具有静态类型安全性的自然外观C++代码.函数调用,派生到基础的转换和接口转换通常需要调用QueryInterface才能获得正确的接口指针.

您可以使用库解决方案(例如,参见WRL库或几乎任何COM代码)来执行此操作,但您不能支持C++语言功能,如隐式转换或dynamic_cast.如果没有帽子,你就只能处理接口指针而不得不打电话给QueryInterface自己.


(如果你有兴趣的理由,为什么在C++/CX语言扩展,开发和C++/CLI语法如何最终被选取为重复利用,我建议吉姆·斯普林菲尔德的职位上由去年的这个博客,"里面的C++/CX Design".另外值得注意的是GoingNative的第3集,其中Marian Luparu讨论了C++/CX.)