2012-11-21 53 views
-1

我有几个非托管的C++类互相引用。为了避免在实例被释放时悬挂指针,我使用boost智能指针,主要是shared_ptr。到现在为止还挺好。悬挂在托管C++包装的指针

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

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

但是,Wheel的4个旧托管实例仍处于托管环境的范围内,现在包含指向旧的非托管实例的悬挂指针。任何想法如何认识到一个包装的本地等价物被处置?一个简单的任务与智能指针。我可以在托管代码中使用它们吗?

回答

0

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

class Base 
{ 
    int refCount = 0; 

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

然后用它作为所有这些的基类,并记住调用的AddRef,当你获得类和Release(实例),当你不再需要它(例如,在析构函数)。您必须在您的C++/CLI类中执行相同的操作;实现一个IDisposable接口并在Dispose()方法中清除保存的本地类实例。使用它不应该有太大问题,因为你只需要在构造函数中调用AddRef,并且在析构函数/ Dispose中调用一次。

+0

我已经在本地代码中使用shared_ptr智能指针保留了一个refcount(boost正在为我做)。当然,我不能开始计数。我的问题是,我不能在C++/cli中使用来自本地C++的boost :: shared_ptr(或者我无法弄清楚)。 CLR不支持非托管类型作为类成员变量。你可以有一个指向NativeClass *但不是boost :: shared_ptr 的指针。 –

+0

这就是为什么我建议你自己实现一个引用计数机制,而不是使用boost :: shared_ptr。这样您就可以始终从托管代码调用Release()。 – Spook

+0

感谢您的帮助。但是这怎么解决悬挂指针问题呢?假设Release()从本机代码本身(而不是托管代码)调用,并且refCount达到零,则删除它。本机代码很好。但是管理的对象仍然对已删除的本地类有一个悬而未决的引用。 –