C ++ Ref类不是System :: IDisposable的成员;无法实现IDisposable

时间:2010-02-07 17:38:38

标签: c++-cli implementation idisposable

我想创建一个名为“Person”的自己的对象类的全局向量。但是,编译器说

    error C2039: '{dtor}' : is not a member of 'System::IDisposable'
1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable'

所以我查看了如何实现IDisposable(我现在知道它主要用于非托管资源),但似乎仍无法实现以下内容:

ref class Globals : System::IDisposable
{  
public: 
  static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    void Dispose()
    {
         delete person_data;
    }
}; 

我得到的两个错误是:

error C2605: 'Dispose' : this method is reserved within a managed class
1>        did you intend to define a destructor?
error C3766: 'Globals' must provide an implementation for the interface method 'void System::IDisposable::Dispose(void)'
1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable::Dispose'

5 个答案:

答案 0 :(得分:3)

您不必明确派生自IDisposable。在MSDN doco之后,使用以下模式:

ref class Globals
{
public:
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    !Globals() // finalizer
    {
        delete person_data;
    {
protected:
    ~Globals() // destructor calls finalizer
    {
        this->!Globals();
    }
};

答案 1 :(得分:0)

使用析构函数。在C ++ / CLI中,ClassName()是Dispose()和!ClassName()等同于C#的~ClassName()。在你的情况下:

ref class Globals : System::IDisposable
{  
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    void ~Globals()
    {
        delete person_data;
    }
}; 

答案 2 :(得分:0)

答案 3 :(得分:0)

您不需要直接或通过析构函数自己实现Dispose()。隐式生成的析构函数已经破坏了所有成员对象。 IDisposable接口将自动添加,不要明确提及。

接下来,您需要决定person_data是一个句柄(必须设置为使用gcnew创建的实例)还是成员对象语义(如堆栈语义,构造函数由父项的构造函数自动调用)对象,当父对象的生命周期结束时自动调用析构函数,并使用“。”而不是“ - &gt;”来访问成员。)

此外,您确定要在“Globals”的所有实例之间共享person_data的一个副本,但是要被处置的第一个实例销毁,而其他任何实例都保留无效引用(引用已处置对象)?看起来你在这里尝试使用Singleton反模式,这是正确的吗?

答案 4 :(得分:-1)

来自 C ++ / CLI in Action C ++ / CLI Dispose模式具有以下规则(转述):

  • 如果一个班级有终结者或者 编译器生成的析构函数 Dispose(bool)将会调用 基于的终结器或析构函数 bool值。IDisposable
  • 如果它只有一个d'tor(~type),那么编译器调用 处置(true)以便调用d'tor。
  • 如果它只有一个终结器(!类型) 然后编译器调用 处理(假)所以终结器是 称为

同样适用于第二条规则:编译器将为您实现Dispose()接口(通过生成SuppressFinalize)。然后使用error C2039: '{dtor}' : is not a member of 'System::IDisposable'确保不调用终结器。

我对你的代码做了这个,我可以让它编译的唯一方法是使person_data成为实例成员。我在静态时得到的错误是delete,这没什么意义。

另外,你是否需要{{1}} person_data向量,因为它是一个托管对象?也许你这样做,但我没有使用cliext足以说出来。

编辑也许这个article的第一段有答案(强调我的):

  

将成员变量声明为   静态和应用程序时   启动时,编译器会创建一个副本   那个成员。这个成员会   由编译器维护的同时   程序正在运行。如果你宣布一个   类的实例,如上所述   车辆变量,静态成员是   不是对象的一部分:编译器   创建并维护静态   会员,无论你是否使用,   是否声明了一个类变量   或不。