托管c+中的悬空指针+;包装纸 我有几个互相引用的非托管C++类。为了避免在发布实例时挂起指针,我使用了boost智能指针,主要是共享的\u ptr。到目前为止还不错

托管c+中的悬空指针+;包装纸 我有几个互相引用的非托管C++类。为了避免在发布实例时挂起指针,我使用了boost智能指针,主要是共享的\u ptr。到目前为止还不错,c++,c++-cli,wrapper,C++,C++ Cli,Wrapper,然而,我在C++/CLI中也有一个包装器,在这个包装器中,几乎每个非托管类都有其托管等价物,以将其公开给.NET应用程序。包装器非常简单,但是我被迫使用不安全的指针从ManagedClass引用UnmanagedClass*。我不能将boost::shared_ptr用作ManagedClass的成员,因为CLR不支持非托管类型作为类成员(只支持指向它们的指针) 示例:class Car,其中包含4个class Wheel实例。5个非托管实例中的每一个都有5个等效的托管实例。非托管汽车可能需要更

然而,我在C++/CLI中也有一个包装器,在这个包装器中,几乎每个非托管类都有其托管等价物,以将其公开给.NET应用程序。包装器非常简单,但是我被迫使用不安全的指针从ManagedClass引用UnmanagedClass*。我不能将boost::shared_ptr用作ManagedClass的成员,因为CLR不支持非托管类型作为类成员(只支持指向它们的指针)

示例:class Car,其中包含4个class Wheel实例。5个非托管实例中的每一个都有5个等效的托管实例。非托管汽车可能需要更改其轮子,它将删除非托管轮子的4个实例,并创建4个新实例。托管汽车要求新的非托管控制盘创建4个新的控制盘托管实例


但是,Wheel的4个旧托管实例仍在托管世界的作用域中,现在包含一个指向旧非托管实例的悬空指针。你知道如何实现包装器的本地等价物被处理了吗?使用智能指针的简单任务。我可以在托管代码中使用它们吗?

为什么不使用内部实例计数?创建基本本机类:

class Base
{
    int refCount = 0;

public:
    void AddRef() { refCount++; }
    void Release() { refCount--; if (refCount == 0) delete this; }
}

然后将其用作所有这些的基类,并记住在获取class实例时调用AddRef,在不再需要时调用Release()(例如在析构函数中)。在C++/CLI类中也必须这样做;在Dispose()方法中实现IDisposable接口并清除保留的本机类实例。使用它应该不会有太大问题,因为您只需要在构造函数中调用一次AddRef,在析构函数/Dispose中调用一次Release。

我已经在本机代码中保留了一个refcount(boost正在为我做这件事),并使用共享的\u ptr智能指针。当然我不能再开始计数了。我的问题是,我不能使用相同的Booo::C++/CLI中的来自原生C++ C++的SyrdypTR(或者我不知道如何)。CLR不支持非托管类型作为类成员变量。您可以使用指向NativeClass*的指针,但不能使用boost::shared_ptr。这正是我建议您自己实现引用计数机制的原因,而不是使用boost::shared_ptr。这样,您将始终能够从托管代码中调用Release()。感谢您的帮助。但这如何解决悬而未决的指针问题呢?假设从本机代码本身(而不是从托管代码)调用Release(),并且refCount达到零,请删除此项。本机代码很好。但是托管对等方仍然有一个对已删除的本机类的悬空引用。如果托管对等方获得了该引用,那么它应该调用AddRef。在这种情况下,如果本机代码调用Release(),refcount将达到1,并且类将保持不变。事实上,您可能能够实现自己的“安全指针”,它将作为本机指针的包装器,并在构造函数中调用AddRef,在Finalize()或Dispose()方法中调用Release()(如果您可以确定不再需要指针的确切时刻),您将能够实现自己的托管“安全指针”。