将非托管/非托管成员添加到托管类

时间:2017-10-07 09:20:11

标签: c# c++ visual-c++ c++-cli

感谢您的关注。我是一些VS2013代码的新手,它是C ++和一些微软特定扩展的混合体。代码有类似

的类
ref class Foo {
    Bar^ bar_; // somewhere else, bar_ = gcnew Bar...
};

现在我需要添加一个非托管成员,从在线搜索看来我似乎可以做到

ref class Foo {
    Bar ^ bar_;
    Unmanaged* ptr_; // somewhere else, ptr = new Unmanaged();
    ~Foo() {
        this->!Foo();
    }
    !Foo() {
        delete ptr_;
        // do I need anything to deal with bar_?
    }
};

问题是:

1)这个终结器/析构器是要走的路吗?

2)我是否需要为bar_编写额外的内容,因为我明确写了终结器/析构函数?

3)有更干净的方法吗?

1 个答案:

答案 0 :(得分:3)

  

1)这个终结器/析构器是要走的路吗?

  

2)我是否需要为bar _

编写额外的内容

片段中没有任何明显的内容。但是如果Bar类也是一次性的,那么你可能应该将delete bar_;添加到析构函数中。不是终结者。如果您将引用传递给其他代码,那么就不能确定此引用是最后一个仍使用Bar对象的引用。

  

3)有更干净的方法吗?

没有。有其他方法可以做到这一点。例如,您可以考虑不添加析构函数。有一个给使用该类的代码调用它的负担。通常情况下,这将是C#或VB.NET代码,它必须使用using语句或显式调用Dispose()。请记住,他们经常忘记。或者没有一个好方法来打电话。

如果不希望这样的代码创建很多Foo实例,而Unmanaged类只使用一点内存,那么终结器可能就足够了。或者,如果Foo对象预计会在应用程序的生命周期中存活,这很常见,那么处理是没有意义的。即使它确实使用了大量内存,GC :: AddMemoryPressure()也是一个非常好的选择。使您的课程更容易使用。

你可以考虑将Unmanaged指针包装在它自己的类中,这样Foo就不再需要终结器了。沿着.NET中的SafeHandle类的模式,SafeBuffer是最接近的匹配。这往往是矫枉过正,但在C ++ / CLI包装器中,delete失败尤其不是你想要隐藏的。

但是你所拥有的就完成了工作。