gpt4 book ai didi

c++-cli - 我应该在 C++/CLI 类中使用 C# 对象的引用还是实例吗?

转载 作者:行者123 更新时间:2023-12-02 11:53:27 28 4
gpt4 key购买 nike

在托管 C++ 类中,我应该使用在另一个库中实现的 C# 类的引用还是实例吗?

考虑这个例子:

// MyManagedClass.h
#pragma once

using namespace System::Collections::Generic;
using namespace My::Namespace::MyCSharpLib;

namespace My::Namespace::MyManagedLib
{
public ref class MyManagedClass
{
public:
MyCSharpClass myInst; // i have an instance!
MyCSharpClass ^myRef; // need to do gcnew

List<MyCSharpClass ^> listInst; // i have an instance!
List<MyCSharpClass ^> ^listRef; // need to do gcnew
};
}

然后从 C# 代码调用托管类:

// driver.cs
using My.Namespace.MyCSharpLib;
using My.Namespace.MyManagedLib;

public class Driver
{
private static void Main(string[] args)
{
MyManagedClass mmc = new MyManagedClass();
DoStuff(mmc);
}
}

我的直觉告诉我我应该使用 myReflistRef 因为如果这是在 C# 中实现的话我就会这样做。但为什么我可以直接实例化 MyCSharpClass 的实例?这样做的后果是什么?如果我的类只有一个 MyCSharpClass 对象集合,那么直接初始化该集合是否有危害?

最佳答案

C++/CLI 有一个名为 stack semantics 的功能,当您将引用类型成员声明为值类型时使用它 (MyCSharpClass myInst;)。

gcnew 仍在被调用,但您看不到此代码,因为编译器会将其自动注入(inject)到您的默认构造函数中。请注意,它还会生成处理 myInst 的代码!

下面是编译器将为您的类发出的与 MSIL 等效的(伪)C++/CLI 代码:

构造函数:

MyManagedClass()
{
myInst = gcnew MyCSharpClass();
}

处置:

void Dispose(bool dispose)
{
if (dispose)
{
try
{
this->~MyManagedClass();
}
finally
{
delete myInst;
}
}
}

编辑:

关于您有关影响的问题:使用 gcnew 手动分配意味着当您的 MyManagedClass 对象死亡时,myRef 指向的对象仍然会徘徊直到垃圾收集器将其清理干净;而通过使用堆栈语义,您可以更确定地控制对象生命周期,而无需自己编写 Dispose 方法。

这也意味着在使用堆栈语义时,您必须小心与谁共享对象......

关于c++-cli - 我应该在 C++/CLI 类中使用 C# 对象的引用还是实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29931239/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com