我不太明白 shared_ptr 和 C++/CX 中的新句柄符号 (^) 之间的区别。从我读过的内容来看,他们似乎在引用计数和内存管理方面做同样的事情。我错过了什么?
std::shared_ptr<Type>
//vs
Type^
我不太明白 shared_ptr 和 C++/CX 中的新句柄符号 (^) 之间的区别。从我读过的内容来看,他们似乎在引用计数和内存管理方面做同样的事情。我错过了什么?
std::shared_ptr<Type>
//vs
Type^
仅考虑生命周期管理,它们是相同的: ashared_ptr<T>
持有对T
对象的强(拥有)引用;aT^
也一样。 make_shared<T>
大致相当于ref new T
在 C++/CX 中。
如果你在任何地方看到T^
你认为的shared_ptr<T>
orComPtr<T>
或CComPtr<T>
,那没关系 - 生命周期管理大致相同。
但是,生命周期管理在底层的工作方式是不同的:每种格式正确的T
类型T^
都是实现IUnknown
接口的 Windows 运行时引用类型,因此T
对象是内部引用计数(*)。 shared_ptr<T>
支持任意类型并使用外部引用计数(即,它分配自己的引用计数机制来控制对象的生命周期)。
对于弱引用,shared_ptr<T>
hasweak_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
自己。
(If you're interested in the rationale behind why the C++/CX language extension were developed and how the C++/CLI syntax ended up being selected for reuse, I'd recommend Jim Springfield's post on this blog from last year, "Inside the C++/CX Design". Also of note is episode 3 of GoingNative, in which Marian Luparu discusses C++/CX.)
据我所知,后者缺乏对弱引用和自定义释放函数的支持。
请注意,前者更通用,接受任何类型(原则上),并且为了安全和清洁要求使用辅助函数make_shared
。后者在语言级别上得到支持。这意味着这样的代码在 C++/CX 中是安全的:
some_function(ref new foo(), ref new bar());
在 C++ 中,您需要这样做:
// bad: if foo is allocated but bar's allocation throws, you leak!
some_function(new foo(), new bar());
// good: both never make it anywhere but into a shared_ptr, no leaks
some_function(make_shared<foo>(), make_shared<bar>());
除此之外,当然,它们实现了相同的概念。如果您在 C++/CX 领域,请使用后一种语法以简化和统一;如果您尝试使用标准 C++,或者将现有资源管理方案包装到引用计数方案中,那么您将需要前者。