C++ Ref 类不是 System::IDisposable 的成员;实施 IDisposable 时遇到问题

发布于 2024-08-20 17:51:52 字数 971 浏览 5 评论 0原文

我想为我自己的对象类创建一个名为“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;
    }
}; 

我得到的 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'

I want to make a global vector of my own object class called "Person". However, the compiler says that

    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'

So I looked up how to implement IDisposable (which I now know is used primarily for unmanaged resources) but still can't seem to implement it with the following:

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

The 2 errors I get are:

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

铜锣湾横着走 2024-08-27 17:51:52

您不必显式从 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();
    }
};

You don't have to explicitly derive from IDisposable. Following the MSDN doco, use the following pattern:

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();
    }
};
冷夜 2024-08-27 17:51:52

使用析构函数。在 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;
    }
}; 

Use a destructor. In C++/CLI ~ClassName() is Dispose() and !ClassName() is equivalent to C#'s ~ClassName(). In your case:

ref class Globals : System::IDisposable
{  
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
    void ~Globals()
    {
        delete person_data;
    }
}; 
看透却不说透 2024-08-27 17:51:52

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

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

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

You don't need to implement Dispose() yourself, either directly or via a destructor. The implicitly-generated destructor already destroys all member objects. The IDisposable interface will be added automatically, don't mention it explicitly.

Next, you need to make up your mind whether person_data is a handle (which has to be set to an instance created with gcnew) or member object semantics (like stack semantics, the constructor is automatically called by the constructor of the parent object, the destructor called automatically when the lifetime of the parent object ends, and you use "." instead of "->" to access members).

Also, are you sure you want one copy of person_data shared between all instances of "Globals", but destroyed by the first instance to be disposed, leaving any other instances holding an invalid reference (reference to disposed object)? It looks like you're trying to use a Singleton anti-pattern here, is that correct?

小瓶盖 2024-08-27 17:51:52

来自C++/CLI 实际操作 C++/CLI Dispose 模式具有以下规则(解释):

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

第二条规则:编译器将为您实现IDisposable接口(通过生成Dispose())。然后,它使用 SuppressFinalize 来确保不会调用终结器。

我对您的代码执行了此操作,编译它的唯一方法是使 person_data 成为实例成员。当它是静态时我得到的错误是 error C2039: '{dtor}' : is not a member of 'System::IDisposable' 这没有多大意义。

另外,您是否需要删除 person_data 向量,因为它是托管对象?也许你会这样做,但我还没有使用过足够多的客户端。

编辑也许这篇文章的第一段有答案(强调我的):

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

From C++/CLI in Action The C++/CLI Dispose pattern has these rules (paraphrased):

  • If a class has a finalizer or a
    destructor the compiler generates
    Dispose(bool) that will call either
    the finalizer or destructor based on
    the bool value.
  • If it has just a d'tor (~type) then the compiler calls
    Dispose(true) so the d'tor is called.
  • If it has just a finalizer (!type)
    then the compiler calls
    Dispose(false) so the finalizer is
    called

Also for the second rule: The compiler will implement the IDisposable interface for you (by generating Dispose()). It then uses SuppressFinalize to make sure the finalizer isn't called.

I did this to your code and the only way I could get it to compile was to make person_data a instance member. The error i got when it was static was error C2039: '{dtor}' : is not a member of 'System::IDisposable' which doesn't make much sense.

Also, do you even need to delete the person_data vector since is a managed object? Maybe you do but I haven't used the cliext enough to say.

Edit Perhaps the first paragraph of this article has the answer (emphasis mine):

When you declare a member variable as
static and when the application
starts, the compiler creates a copy of
that member. This member would be
maintained by the compiler while the
program is running. If you declare an
instance of a class, like the above
vehicle variable, the static member is
not part of the object: the compiler
creates and maintains the static
member, whether you use it or not,
whether you declare a class variable
or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文