2010-02-07 60 views
3

我想制作一个名为“Person”的我自己的对象类的全局向量。然而,编译器说,C++ Ref类不是System :: IDisposable的成员;麻烦实施IDisposable

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; 
    } 
}; 

的2个错误,我得到的是:

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' 

回答

-1

C++/CLI中行动的C++/CLI处置图案具有这些规则(转述):

  • 如果类具有一个终结或编译器生成的 析构函数 Dispose(bool)将根据 ,bool值调用 终结器或析构函数。
  • 如果它只有一个(〜型),那么编译器会调用 Dispose(true),这样调用者就会被调用。
  • 如果它只是一个终结 那么编译器调用 的Dispose(假),这样终结的 叫

对于第二规则(类型!):编译器将实现IDisposable接口让您(通过生成Dispose())。然后它使用SuppressFinalize来确保终结器未被调用。

我这样做了你的代码,我可以让它编译的唯一方法是使person_data成为一个实例成员。我在静态时得到的错误是error C2039: '{dtor}' : is not a member of 'System::IDisposable',这没有多大意义。

另外,你甚至需要delete person_data向量,因为它是一个托管对象吗?也许你会这样做,但我还没有使用足够的说法。

编辑也许这article第一款有答案(重点煤矿):

在声明成员变量 静态和当应用程序 开始,编译器创建的副本 该成员。当编译器运行 程序时,该成员将为 。如果您声明一个类的 例如,像上面 车辆变量,静态成员是 对象的不部分:编译 创建和维护静态 成员,无论您使用与否, 是否你声明一个类变量 或不。

+0

感谢您的回复,我认为这确实会有诀窍。不知道为什么那个析构错误不断出现。 – Dororo 2010-02-08 18:47:04

+0

我似乎无法找到关于释放析构函数或终结器中的静态成员的任何信息。也许有人在那里知道答案并将分享。 – cmw 2010-02-08 19:01:00

+0

静态成员由.cctor初始化,而不是在应用程序启动时初始化 – 2010-02-23 16:22:03

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; 
    } 
}; 
+0

编译器然后说析构函数不能有返回类型。然而,删除'void'会使编译器无法将该函数识别为IDisposable的实现(因为它的形式可能是void func(void)?) – Dororo 2010-02-07 18:00:14

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(); 
    } 
}; 
+0

感谢您的帮助,但我仍然收到以下错误消息: static cliext :: vector person_data = gcnew cliext :: vector ; 编译器指出析构函数不是IDisposable的成员: 1>错误C2039:'{dtor}':不是'System :: IDisposable'的成员 1> c:\ windows \ microsoft.net \ framework \ v2.0.50727 \ mscorlib.dll:请参阅'System :: IDisposable'声明 即使确保Person类确实是IDisposable,它仍然拒绝编译。 – Dororo 2010-02-08 07:16:45

+0

我可以编译的唯一方法是从person_data中删除'static'关键字。只要你有一个类型cliext :: vector 的静态成员,你会得到这个错误 - 我试图删除person_data并用cliext替换它:: vector int_data = gcnew cliext :: vector ;并仍然有相同的错误!它超出了我的技能。 – mcdave 2010-02-08 11:45:32

+0

你不能删除什么不是句柄 – 2010-02-23 16:18:33

0

您不需要直接或通过析构函数自己实现Dispose()。隐式生成的析构函数已经销毁所有成员对象。 IDisposable接口将自动添加,不要明确提及它。接下来,您需要下定决心person_data是一个句柄(必须设置为使用gcnew创建的实例)还是成员对象语义(如堆栈语义,构造函数会自动由父对象,在父对象的生命周期结束时自动调用析构函数,并且使用“。”而不是“ - >”来访问成员)。

另外,你确定你想要在所有“Globals”实例之间共享person_data的一个拷贝,但是被第一个实例销毁,留下任何持有无效引用的其他实例(引用已处理对象)?它看起来像你试图在这里使用Singleton反模式,这是正确的吗?