auto foo = ref new Foo();啥是“参考”?

Posted

技术标签:

【中文标题】auto foo = ref new Foo();啥是“参考”?【英文标题】:auto foo = ref new Foo(); What is "ref"?auto foo = ref new Foo();什么是“参考”? 【发布时间】:2011-11-23 17:11:40 【问题描述】:

我正在观看来自 //build/ 的视频,一些 MS 开发人员在他们的 C++11 程序中使用了这样的语法:

auto foo = ref new Foo();

我了解这一行中除了“ref”之外的所有内容。这是什么意思?

【问题讨论】:

所以没有人会误解:这不是 C++11 语法!这是微软的扩展。 您应该在 14:30 观看此视频“使用 C++ 中的 Windows 运行时”channel9.msdn.com/events/BUILD/BUILD2011/TOOL-532T 【参考方案1】:

即将推出的 Visual C++ 编译器添加了这种语法来处理 WinRT 对象(它们又是下一代 COM,我们现在经历了什么?COM、DCOM、COM+、ActiveX,...)

该行几乎等同于:

com_ptr_t<Foo> foo = CreateInstance<Foo>();

但还有一个新版本的com_ptr_t,使用语法Foo^

【讨论】:

这让我觉得有点激进的语法滥用。我不知道 WinRT,但这会在 C++(本机)堆上创建一个动态实例吗? @KerrekSB:很确定它使用操作系统分配器,就像 COM 对象传统上所做的那样(但就像其他所有东西一样,我确信有一个新的和改进的 WinRT 分配器而不是 the good-ol' COM allocator)。所以它是堆上的动态实例,而不是由 C++ 运行时管理并用于newdelete 的堆。 @Ben 我不声称知道这个设计决定的具体原因,但是在 ATL 中编写 C++ 和 COM 代码的几年中立即想到的一件事是智能指针实现为模板类不能很好地与不使用它们的 API 配合使用——您最终不得不在 API 边界将原始指针显式包装/解包到智能指针中。一个特别糟糕的情况是指针是一个输出参数 - 所以你最终必须在包装它之前为其提供一个原始指针变量 - 或者像 ATL 那样重载一元 &amp; 并破坏 STL。 @PavelMinaev:重载 operator&amp; 不再违反 STL 约束。其次,设计用新东西编写的 API 可能只需要com_ptr_t。然而,Herb Sutter 说他们几乎确实在 C++ 中将它变成了库,但是有一些奇怪的边缘情况会产生非常糟糕的库性能,他们必须使它成为语言来解决这些问题。语法增强本身已经在 C++/CLI 的编译器中。 @DeadMG:你会不会碰巧有一个链接到 Herb Sutter 的详细信息?【参考方案2】:

"ref new" 是一个 2 标记关键字。它指示编译器实例化一个 Windows 运行时对象并自动管理对象的生命周期(通过“^”运算符)。

实例化 Windows 运行时对象会导致分配,但它不必在堆上。

【讨论】:

参考是双模式值/参考吗?当引用超出范围时,是否将其视为 CComPtr?可以像普通类一样在堆栈上实例化 ref 类吗? WinRT/C++/CX 是否支持我旧的基于 COM 的代码(接口以及基于 ATL 的实现)?抱歉,突然出现的问题... 这些不是引用——“ref new”是语言关键字,就像“new”和“__gcnew”一样。因此,您不能在堆栈上实例化它们(您可以在堆栈上实例化指针吗?)。 WinRT 是 API 的集合和 API 模式的集合,所以说它支持基于 COM 的代码是没有意义的。 C++/CX 支持经典 COM API,就像 C++/CLI 支持经典 COM API 一样。您可以在 C++/CX 应用程序中使用 ATL,也可以使用新的 WRL 模板库 (ComPTR)。 我在任何示例中都没有看到对 Release() 的任何显式调用,所以我猜编译器会在句柄/指针/引用(无论它们被称为什么)时注入对 Release() 的调用在 CX 中)超出范围。这是一个正确的猜测吗? 没错——这就是我所说的“自动管理对象的生命周期” 根据我在 msdn 上阅读的内容,^ 引用包含两个指针,一个指向对象,一个指向类定义,它们的创建删除行为与 C++11 shared_ptr 的行为相同.我对指向类定义的指针的假设是因为 WinRT 对象很容易传递给其他 WinRT 语言(C# 和 javascript)的包。 (msdn.microsoft.com/en-us/library/windows/apps/hh699870.aspx)【参考方案3】:

ref 在这种情况下代表引用计数。使用 ref 的类是 WinRT 组件,它具有开箱即用的引用计数机制。

【讨论】:

以上是关于auto foo = ref new Foo();啥是“参考”?的主要内容,如果未能解决你的问题,请参考以下文章

`raise "foo"` 和 `raise Exception.new("foo")` 有啥区别?

“new Foo()”和“&Foo()”作为参数的区别

在 PHP 中,当 $foo = new Foo() 时,从技术上讲,$foo 是一个对象,还是 $foo 一个引用?

熊猫分组总和

new new Foo().getName() 一道前端面试题引发的思考

有没有办法删除传递给函数 `foo (new Object())` 的对象?