std::shared_ptr<Type> 和 Type^ 之间的区别
Difference between std::shared_ptr<Type> and Type^
我真的不明白C++/CX中shared_ptr和新句柄表示法(^)之间的区别。从我读到的内容来看,他们在引用计数和内存管理方面似乎做了同样的事情。我错过了什么?
std::shared_ptr<Type>
//vs
Type^
仅考虑寿命管理,它们是相同的:shared_ptr<T>
持有对T
对象的强(拥有)引用;CCD_ 3也做同样的事情。CCD_ 4与C++/CX中的CCD_。
如果你在任何地方看到T^
,你都会想到shared_ptr<T>
、ComPtr<T>
或CComPtr<T>
,那么没关系——寿命管理大致相同。
不过,生存期管理在后台的工作方式是不同的:T^
格式良好的每个T
类型都是实现IUnknown
接口的Windows运行时引用类型,因此T
对象是内部引用计数的(*)。shared_ptr<T>
支持任意类型并使用外部引用计数(即,它分配自己的引用计数机制来控制对象的生存期)。
对于弱引用,shared_ptr<T>
具有weak_ptr<T>
,T^
具有WeakReference
。WeakReference
不是强类型的,但你可以很容易地围绕它编写一个强类型引用包装。否则,弱引用会像你期望的那样工作。对弱引用的支持是可选的:不是所有引用类型都支持弱引用,但大多数都支持。
(*)有一个例外:Platform::String^
,它不是Windows运行时引用类型,但由于各种原因而被特殊处理。不过,在终身管理方面,您可以将其视为与任何其他T^
相同
那么,为什么Windows运行时类型在C++/CX中戴帽子呢?为什么不使用像shared_ptr<T>
或ComPtr<T>
这样的库解决方案?
这是因为你从来没有真正的指向具体运行时类型的指针(或帽子):你只能通过指向其类型实现的接口之一的指针与对象交互。Windows Runtime也不支持接口或类继承:每个接口都必须直接从IInspectable
派生,并且类继承是通过使用COM聚合来模拟的。
简言之,没有任何库解决方案可以产生具有静态类型安全性的自然外观的C++代码。函数调用、派生到基的转换和接口转换通常需要调用QueryInterface
才能获得正确的接口指针。
您可以使用库解决方案(例如,请参阅WRL库或几乎任何COM代码)来实现这一点,但您不能支持C++语言功能,如隐式转换或dynamic_cast
。如果没有帽子,您只能处理接口指针,并且必须自己调用QueryInterface
。
(如果你对为什么开发C++/CX语言扩展以及C++/CLI语法最终是如何被选择重用感兴趣,我推荐Jim Springfield去年在这个博客上发表的文章"C++/CX设计内幕"。另外值得注意的是GoingNative的第3集,Marian Luparu在其中讨论了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++,或者将现有的资源管理方案包装为引用计数方案,那么您将需要前者。
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 不同指针类型之间的无效比较:'type*' 和 'type&(*)()'
- std::shared_ptr<Type> 和 Type^ 之间的区别
- 错误"does not name a type"和"has not been declared"之间的区别
- c++ 我需要在结构中存储具有继承和虚函数的各种类之间的对象"type"
- 对<type>链表使用列表和指针(经典 C)之间的差异