C++/CLI 析构函数

3

我有一个混合语言的应用程序(包括C#,C++/CLI和本地C++),我正在通过在几个对象的构造函数和析构函数中放置日志语句来跟踪一些对象的生命周期。我有一个C#对象,其中包含对C++/CLI对象的引用。

public class MyC#Class
{
    public MyC#Class() { log.Debug("created MyC#Class object " + this.GetHashCode()); }
    ~MyC#Class() { log.Debug("destroyed MyC#Class object " + this.GetHashCode()); }
    private MyC++Class myC++Obj = new MyC++Class();
}
MyC++Class::MyC++Class() { loggerInt1(LOGDEBUG, "created MyC++Class object %d", (int)this->GetHashCode());
MyC++Class::~MyC++Class() { loggerInt1(LOGDEBUG, "destroyed MyC++Class object %d", (int)this->GetHashCode());

问题在于当C#对象被垃圾回收时,我能看到来自C#析构函数的日志语句,但是我看不到来自C++/CLI对象的日志语句。换句话说,我看到了“销毁MyC#Class对象XXXX”,但我没有看到相应的“销毁MyC++Class对象YYYY”。据我所知,对于C#和C++/CLI,析构函数会覆盖GC通常调用的Finalize()方法,因此当MyC++Class对象被垃圾回收时,MyC++Class析构函数的日志语句将被打印出来。
除非MyC++Class对象被其他东西引用,因此还未到达GC的时间,否则是否有人知道为什么MyC++Class析构函数的日志语句没有被打印?
谢谢。

映射是不同的。你的MyClass是C#中的Dispose方法。缺少的!MyClass是C#中的析构函数。在任何其他语言和.NET文献中称为终结器。你没有看到MyClass被调用,因为没有人处理该对象。你没有看到!MyClass被调用,因为你没有编写它。 - Hans Passant
在你的代码中使用非法的类名并不能解决问题。尝试使用CppClassCsClass代替C++C# - Ben Voigt
1个回答

14

C++/CLI的析构函数并不同于C#的finalizer/destructor。 C++/CLR的析构函数不重写Finalize(),且在垃圾回收期间不会被调用。 C++/CLR有不同的语法来声明finalizer,例如在您的情况下可以使用MyC++Class::!MyC++Class

C++/CLI的析构函数相当于在C#中实现IDisposable接口,并且确实实现了IDisposable接口。 要从C#代码中调用C++/CLI的析构函数,您需要调用Dispose()方法。 这在C++/CLR文档中明确说明。


我将MyC++Class::~MyC++Class()更改为MyC++Class::!MyC++Class(),但最终器中的日志语句仍未打印。 - Thomas Nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接