如何包装在构造函数中传递非托管类的类



我试图理解c++/CLI,所以我可以为c++代码创建包装器类。我的问题是,我有一个类,它存储一个指针到该类的父对象,因此我需要传递它到类。

下面是一个例子,但是完整的类有更多的函数和存储额外的数据。

class A
{
private:
    A* parent;
public:
    A(A* Parent)
    {
        parent = Parent;
    }
    ~A()
    {
        delete parent;
    }
    A* GetParent()
    {
        return parent;
    }
}

我目前的想法是有一个非公共构造函数,这样你就可以用非托管类构造一个托管类,而不需要在类外访问它。

public ref class ManagedA
{
    A* unmanaged;
    ManagedA(A* unmanaged)
    {
        this->unmanaged = unmanaged;
    }
public:
    ManagedA(ManagedA^ Parent)
    {
        unmanaged = new A(Parent->unmanaged);
    }
    ~ManagedA()
    {
        delete unmanaged;
        unmanaged = NULL;
    }
    ManagedA^ GetParent()
    {
        return gcnew ManagedA(unmanaged->GetParent());
    }
}

虽然这适用于类内的函数,但如果我想创建一个对象,或者如果我有一个需要传入非托管类的函数,我仍然会遇到问题。

有什么办法可以解决这个问题吗?

ManagedA^ GetParent()
{
    return gcnew ManagedA(unmanaged->GetParent());
}
你写这样的代码是在玩火自焚,这是非常危险的。问题是,您正在创建引用完全相同A*的多个ManagedA对象。一旦中的一个被销毁,所有其他ManagedA对象现在都有一个悬浮指针。这几乎肯定会导致内存损坏。 解决方法很简单,只需将父引用存储在构造函数中:
public ref class ManagedA {
private:
    A* unmanaged;
    ManagedA^ parent;
public:
    ManagedA(ManagedA^ Parent) : parent(Parent) {
        A* unmanagedParent = Parent == nullptr ? nullptr : Parent->unmanaged;
        unmanaged = new A(unmanagedParent);
    }
    ManagedA^ GetParent() {
        return parent;
    }
    ~ManagedA() {
        this->!ManagedA();
        unmanaged = NULL;
    }
    !ManagedA() {
        delete unmanaged;
    }
};

注意构造函数中添加的nullptr检查,这是我可以看到如何创建第一个A*的唯一相同方式。

这是一种简单的情况,当您需要将A*映射回ManagedA^时,会出现完全相同的对象标识问题。首先检查是否真的需要,客户端代码应该只操作ManagedA对象。必要时,您需要创建一个查找表,以便能够可靠地找到相应的ManagedA^ back。这需要一个静态的Dictionary<IntPtr, ManagedA^>。在构造函数中向字典中添加对象,在终结器中删除对象。注意,您忘了包含终结器,它不是可选的。我将它添加到代码片段中。

相关内容

  • 没有找到相关文章

最新更新