C++ std::shared_ptr<;类型>;和类型^

C++ std::shared_ptr<;类型>;和类型^,c++,c++11,windows-runtime,c++-cx,C++,C++11,Windows Runtime,C++ Cx,我真的不理解C++/CX中共享的ptr和新的句柄符号(^)之间的区别。据我所知,它们在引用计数和内存管理方面似乎做了同样的事情。我错过了什么 std::shared_ptr<Type> //vs Type^ std::共享 //vs 类型^ 据我所知,后者缺乏对弱引用和自定义释放函数的支持 注意,前者更一般,可以接受任何类型(原则上),并且为了安全和清洁,需要使用helper函数make_shared。后者在语言级别上受支持。这意味着这样的代码在C++/CX中是安全的: some_

我真的不理解C++/CX中共享的ptr和新的句柄符号(^)之间的区别。据我所知,它们在引用计数和内存管理方面似乎做了同样的事情。我错过了什么

std::shared_ptr<Type>
//vs
Type^
std::共享
//vs
类型^

据我所知,后者缺乏对弱引用和自定义释放函数的支持

注意,前者更一般,可以接受任何类型(原则上),并且为了安全和清洁,需要使用helper函数
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>());
//错误:如果分配了foo,但bar的分配抛出,那么您就泄漏了!
一些函数(新foo(),新bar());
//好:两者都不会在任何地方出现,但会进入一个共享的ptr,不会泄漏
一些函数(make_shared(),make_shared());

除此之外,当然,它们实现了相同的概念。如果您使用的是C++/CX语言,为了简单和统一,请使用后一种语法;如果你试图坚持标准C++,或者将现有的资源管理方案封装到引用计数的方案中,那么你会想要前者。

< p>据我所知,后者缺乏对弱引用和自定义分配功能的支持。 注意,前者更一般,可以接受任何类型(原则上),并且为了安全和清洁,需要使用helper函数
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>());
//错误:如果分配了foo,但bar的分配抛出,那么您就泄漏了!
一些函数(新foo(),新bar());
//好:两者都不会在任何地方出现,但会进入一个共享的ptr,不会泄漏
一些函数(make_shared(),make_shared());

除此之外,当然,它们实现了相同的概念。如果您使用的是C++/CX语言,为了简单和统一,请使用后一种语法;如果你试图坚持标准C++,或者将现有的资源管理方案包装成引用计数的方案,那么你会想要前者。

< P>单独考虑生命周期管理,这些都是相同的:A<代码> SyddYPPT/<代码>拥有对<代码> T < /Cord>对象的强烈(拥有)引用;a
T^
也会这样做
make_shared
大致相当于C++/CX中的
ref new T

如果你在任何地方看到一个
T^
你认为
shared\u ptr
ComPtr
CComPtr
,那么没关系——生命周期管理大致相同

虽然生命周期管理在引擎盖下的工作方式有所不同:
T
格式良好的每个
T^
类型都是实现
IUnknown
接口的Windows运行时引用类型,因此
T
对象是内部引用计数(*)
shared_ptr
支持任意类型并使用外部引用计数(即,它分配自己的引用计数机制来控制对象的生存期)

对于弱引用,
shared_ptr
具有
weak_ptr
,而
T^
具有
WeakReference
WeakReference
不是强类型的,但是您可以很容易地围绕它编写一个强类型引用包装器。否则,弱引用会像您期望的那样工作。对弱引用的支持是可选的:并非所有引用类型都支持弱引用,但大多数都支持

(*)有一个例外:
Platform::String^
,它不是Windows运行时引用类型,但由于各种原因被专门处理。但是,在生命周期管理方面,您可以将其视为与任何其他
T^
相同


那么,为什么Windows运行时类型在C++/CX中戴帽子呢?为什么不使用像
shared\u ptr
ComPtr
这样的库解决方案

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

P.>总之,没有库解决方案会导致具有静态类型安全性的自然外观C++代码。派生到基转换的函数调用和接口转换通常需要调用
QueryInterface
来获取正确的接口指针

可以用库解决方案(例如,WRL库,或者几乎任何COM代码)来实现这一点,但是不能支持C++语言特性,如隐式转换或<代码> DyrimCysCase。如果没有hats,您将只能处理接口指针,必须自己调用

QueryInterface



(如果您对为什么开发C++/CX语言扩展以及如何选择C++/CLI语法进行重用感兴趣,我推荐Jim Springfield去年在本博客上发表的文章。另外值得注意的是,Marian Luparu在其中讨论了C++/CX。)

仅考虑生命周期管理,这些都是相同的:一个
shared_ptr
持有一个对
T
对象的强(拥有)引用;a
T^
也会这样做
make_shared
大致相当于C++/CX中的
ref new T

如果你在任何地方看到一个
T^
你认为
shared\u ptr
ComPtr
CComPtr
,那么没关系——生命周期管理大致相同

尽管如此,生命周期管理在引擎盖下的工作方式是不同的:
T
格式良好的每个
T^
类型都是Windows运行时引用类型