首页 > 解决方案 > 接受 C++/CLI 中带有和不带有“hat”运算符的托管结构。有什么不同?

问题描述

我有一个已经成功使用了很长时间的 C++/CLI 层。但我刚刚发现了一些让我觉得我需要重新学习一些东西的东西。

当我的 C++/CLI 函数接收到任何托管的实例时,它们会使用“帽子”运算符 ('^'),而当它们接收到托管结构的实例时,它们不会。我以为这是我应该写的。

尽可能平淡地说明

using Point = System::Windows::Point;
public ref class CppCliClass
{
    String^ ReturnText(String^ text) { return text; }  // Hat operator for class
    Point   ReturnStruct(Point pt) { return pt; }      // No hat operator for struct
};

我认为这是必需的。它当然有效。但是就在今天我发现 CancellationToken 是一个结构,而不是一个类。我的代码戴着帽子接受它。写的时候还以为是一堂课。这段代码工作得很好。我的取消在 C++/CLI 层中得到尊重。

void DoSomethingWithCancellation(CancellationToken^ token)
{
    // Code that uses the token.  It works just fine
}

所以显然我可以选择任何一种方法。

但是,按值传入结构(就像我对我使用的所有其他结构类型所做的那样,如 Point)和通过引用(就像我对 CancellationToken 所做的那样?)之间有什么区别。有区别吗?

标签: c++-cli

解决方案


^for 引用类型和没有 for 值类型与 C# 匹配,但 C++/CLI 确实为您提供了更大的灵活性:

  • 没有引用类型称为“堆栈语义”,并在变量生命周期结束时^自动尝试调用对象。IDisposable::Dispose它就像一个 C#using块,除了更加用户友好。尤其:

    • 无论类型是否实现,都可以使用语法IDisposable。在 C# 中,只有using在编译时可以证明类型可以实现IDisposable. C++/CLI 范围内的资源管理在通用和多态情况下工作得很好,其中一些对象可以实现,而另一些则不实现IDisposable

    • 该语法可用于类成员,并IDisposable在包含类上自动实现。C#using块仅适用于本地范围。

  • 使用的值类型^被装箱,但精确的类型被静态跟踪。如果传入不同类型的装箱值,您将收到错误。


推荐阅读