C++ cli 我应该在C+中使用C#objects的引用还是实例+/CLI类? 在托管C++类中,我应该使用在另一个库中实现的C类的引用或实例吗?< /P>

C++ cli 我应该在C+中使用C#objects的引用还是实例+/CLI类? 在托管C++类中,我应该使用在另一个库中实现的C类的引用或实例吗?< /P>,c++-cli,C++ Cli,考虑这个例子: // MyManagedClass.h #pragma once using namespace System::Collections::Generic; using namespace My::Namespace::MyCSharpLib; namespace My::Namespace::MyManagedLib { public ref class MyManagedClass { public: MyCSharpClass m

考虑这个例子:

// 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
    };
}

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

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

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

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

构造函数:

MyManagedClass()
{
    myInst = gcnew MyCSharpClass();
}
void Dispose(bool dispose)
{
    if (dispose)
    {
        try
        {
            this->~MyManagedClass();
        }
        finally
        {
            delete myInst;
        }
    }
}
处置:

MyManagedClass()
{
    myInst = gcnew MyCSharpClass();
}
void Dispose(bool dispose)
{
    if (dispose)
    {
        try
        {
            this->~MyManagedClass();
        }
        finally
        {
            delete myInst;
        }
    }
}
编辑:

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


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

顺便说一句,如果您打算将C++/CLI用于除琐碎工作以外的任何工作,我建议您尝试使用Nishant Sivakumar的“C++/CLI in Action”。这是一个很好的语言功能参考,也将帮助您避免陷阱。谢谢!这让我想到了其他事情。经过一些测试,我了解到
driver.cs
中没有
mmc.myInst
。此外,只有当
MyCSharpClass
具有默认构造函数时,才会编译该类。“生成代码以解除分配myInst”不,它不会。释放仍由垃圾收集器管理。如果对象实现了
IDisposable
,它将自动调用
Dispose
。C++/CLI堆栈语义是使用块的C#
的一个(到目前为止更强大)版本。C++/CLI中的
删除不是释放。这是对目标对象调用
Dispose
(在安全地强制转换为
IDisposable
之后)的一个更好的调用。尽管编辑段落仍然错误地指出,在使用堆栈语义时,垃圾收集器不控制对象生存期。在堆栈语义对象超出范围后,它就被处理掉了(所以大部分是无用的),但它实际上还没有死。根据.NET规则,您至少仍然可以对其调用
Dispose
,并且某些对象可能允许在Dispose之后执行其他操作。正如您所说,通过“共享”对象而进行的引用不是随意的或悬空的指针,尽管使用它们可能会给您带来
ObjectDisposedException