网站制作的付款方式wordpress4.4.2

当前位置: 首页 > news >正文

网站制作的付款方式,wordpress4.4.2,深圳网站建设公司官网,剪辑素材网站^类型 (^) 是 C/CX 最突出的功能之一——当人们第一次看到 C/CX 代码时#xff0c;很难不注意到它。那么#xff0c;^ 类型到底是什么#xff1f;这是类型是一种智能指针类型#xff0c;它自动管理 Windows 运行时对象的生命周期#xff0c;也 提供自动类型转换功能以简化… ^类型 (^) 是 C/CX 最突出的功能之一——当人们第一次看到 C/CX 代码时很难不注意到它。那么^ 类型到底是什么这是类型是一种智能指针类型它自动管理 Windows 运行时对象的生命周期也 提供自动类型转换功能以简化 Windows 运行时对象的使用。 我们将首先讨论如何通过 WRL 使用 Windows 运行时对象然后解释 C/CX 帽子如何工作以使事情变得更简单。 public interface struct IGetValue{int GetValue()  0;};public interface struct ISetValue{void SetValue(int value)  0;};public ref class Number sealed : public IGetValue, ISetValue{public:Number() : _value(0) { }virtual int  GetValue()          { return _value;  }virtual void SetValue(int value) { _value  value; }private:int _value;}; 在这个修改后的 Number 实现中我们定义了一对接口IGetValue 和 ISetValue它们声明了 Number 的两个成员函数然后 Number 实现了这两个接口。除此之外一切看起来应该非常熟悉。 请注意Number 实际上实现了三个 Windows 运行时接口除了 IGetValue 和 ISetValue 之外编译器仍会生成 Number 实现的 __INumberPublicNonVirtuals 接口。由于 Number 的所有成员都是由显式实现的接口IGetValue 和 ISetValue声明的因此编译器生成的 __INumberPublicNonVirtuals 不会声明任何成员。但是此接口仍然是必需的因为它是 Number 类型的默认接口。每个运行时类型都必须有一个默认接口并且默认接口几乎始终对类是唯一的。稍后我们将看到默认接口为何如此重要。 生命周期管理 Windows 运行时引用类型使用引用计数进行对象生命周期管理。所有 Windows 运行时接口包括 Number 实现的所有三个接口都直接派生自 IInspectable 接口而该接口本身又派生自 COM IUnknown 接口。IUnknown 声明了三个成员函数用于控制对象的生命周期并允许类型转换。 MSDN对 IUnknown 生命周期管理的工作原理进行了全面概述。但原理非常简单每当您创建对对象的新引用时都必须调用 IUnknown::AddRef 来增加其引用计数每当您“销毁”对对象的引用时都必须调用 IUnknown::Release 来减少引用计数。引用计数初始化为零在对 AddRef 和 Release 进行一系列调用后当引用计数再次达到零时对象将自行销毁。 当然在使用 C 编程时我们很少实际上从不直接调用 AddRef 和 Release。相反我们应该尽可能地使用智能指针在需要时自动进行这些调用。使用智能指针有助于确保对象不会因错过 Release 而泄漏也不会因过早 Release 或 AddRef 失败而过早销毁。 ATL 包括 CComPtr 和一系列相关的智能指针它们长期以来一直用于 COM 编程用于自动管理实现 IUnknown 的对象的引用计数。WRL 包括 ComPtr它是一种改进和现代化的 CComPtr改进示例ComPtr 不会像 CComPtr 那样重载一元 。 对于那些没有做过太多 COM 编程并且不熟悉 ComPtrs 的人如果您使用过 shared_ptr包含在 C11、C TR1 和 Boost 中ComPtr 在生命周期管理方面实际上具有相同的行为。机制不同ComPtr 使用 IUnknown 提供的内部引用计数而 shared_ptr 支持任意类型因此必须使用外部引用计数但生命周期管理行为相同。 C/CX hat 具有与 ComPtr 完全相同的生命周期管理语义。复制 T^ 时会调用 AddRef 来增加引用计数而当 T^ 超出范围或被重新分配时会调用 Release 来减少引用计数。我们可以考虑一个简单的示例来演示引用计数行为 {T^ t0  ref new A();T^ t1  ref new B();t0  t1;t0  nullptr;} 首先我们创建一个 A 对象并将其所有权赋予 t0。此 A 对象的引用计数为 1因为有一个 T^ 引用了它。然后我们创建一个 B 对象并将其所有权赋予 t1。此 B 对象的引用计数也是 1。 t0 t1 的最终结果是 t0 和 t1 都指向同一个对象。这必须分三步完成。首先调用 t1-AddRef() 来增加 B 对象的引用计数因为 t1 正在获得该对象的所有权。其次调用 t0-Release() 来释放 t0 对 A 对象的所有权。这会导致 A 对象的引用计数降至零并且 A 对象会自行销毁。这会导致 B 对象的引用计数增加到 2。第三也是最后将 t1 设置为指向 B 对象。 然后我们分配 t0 nullptr。这会将 t0 “重置”为空从而导致其释放对 B 对象的所有权。这会调用 t0-Release()导致 B 对象的引用计数减少到 1。 最后执行将到达块的结束括号}。此时所有局部变量都以相反的顺序被销毁。首先t1 被销毁智能指针而不是指向的对象。这会调用 t1-Release()导致 B 对象的引用计数降至零因此 B 对象会自行销毁。然后销毁 t0这是一个无操作因为它为空。 如果我们只关心生命周期管理那么实际上根本不需要 ^ComPtrT 足以管理对象生命周期。 类型转换 在 C 中涉及类类型的某些类型转换是隐式的其他类型转换可以使用强制转换或一系列强制转换来执行。例如如果 Number 及其实现的接口是普通的 C 类型而不是 Windows 运行时类型则从 Number* 到 IGetValue* 的转换将是隐式的我们可以使用 static_cast 或 dynamic_cast 从 IGetValue* 转换为 Number*。 这些转换不适用于 Windows 运行时引用类型因为引用类型的实现是不透明的并且引用类型在内存中的布局未指定。在 C# 中实现的引用类型在内存中的布局可能与在 C 中实现的等效引用类型不同。因此在直接使用 Windows 运行时类型时我们不能依赖 C 语言特定的功能例如隐式派生到基转换和强制转换。 要执行这些转换我们必须改用 IUnknown 接口的第三个成员函数IUnknown::QueryInterface。此成员函数可视为与语言无关的 dynamic_cast它尝试执行到指定接口的转换并返回转换是否成功。由于每个运行时类型都实现 IUnknown 接口并为 QueryInterface 提供自己的定义因此它可以执行任何必要的操作以在实现它的语言和框架中获取正确的接口指针。