【问题标题】:C++ Deleting Static DataC++ 删除静态数据
【发布时间】:2011-10-14 13:37:34
【问题描述】:

如果我有一个包含在堆上分配的私有静态数据且永不更改的类,我应该在什么时候(如果有的话)删除它?

据我了解,永远不会构造一个类本身(因为类不是 C++ 中的第一类对象),那么就没有析构函数来删除其中的静态数据吗?我是 C++ 新手,如果我对 C++ 的理解存在根本性缺陷或者答案很明显,我很抱歉! 在此先感谢,呃。

【问题讨论】:

  • "类不是 C++ 中的第一类对象" 现在那是一个新对象...
  • 天哪,看看我的基本缺陷位
  • 不是批评,只是观察。 ;-]
  • @ildjam:我不确定类是 C++ 中的第一类对象。实际上,它们不能被视为对象,即创建、修改等。它们只能被实例化。类是其他语言中的第一类对象:ruby、python、javascript、objc...
  • @ildjarn:在理论上的 CompSci 中,“是类型对象本身”的问题是一个很好理解的问题。在 C++ 中这个问题的答案是否定的。最接近 C++ 的是 typeid() / std::type_info,它是一个对象描述一个类型。

标签: c++ memory-management static


【解决方案1】:

static 数据表示,它会在程序的整个持续时间内持续存在。

但是,如果你在指针中使用static

static A *pA = new A();

然后你可以删除它,写delete pA。但这并不会使我的第一个陈述无效。因为 static 指针指向的对象不是静态的。它是静态的指针,而不是指针所指向的对象。

【讨论】:

  • 所以就算我新了,也不需要删了吧?那么对于每个新的都应该有一个删除的规则是一个例外?
  • @Ell:static 关键字表示数据“存在于”类中。 new 创建一个不包含任何静态数据的类(对象)的新实例,而是该对象知道其类并在需要时访问其类的数据。
  • @Ell:如果你的静态对象是一个指向动态分配内存的指针,你应该删除它,但通常不是绝对必要的。无论如何,现代系统将在您释放它之后不久回收。指针本身将继续以任何方式继续,它是静态的指针,而不是它指向的对象。
【解决方案2】:

您可以将此课程放在std::unique_ptr。然后它将在程序关闭时自动删除。否则内存泄漏工具会抱怨你的类泄漏。另一方面,这种内存泄漏是无害的,因为程序已经运行完毕。

【讨论】:

  • 谢谢,这很有帮助,但我已将 James 的回答标记为已接受,因为它告诉我我犯了一个错误,即指针是静态的,而不是数据。谢谢:)
【解决方案3】:

如果数据是静态的,则不会在堆上分配,而是 在进程关闭期间被破坏。

如果是指向静态数据的指针,例如:

Something* MyClass::aPointer = new Something;

然后像所有其他动态分配的数据一样,它只会 删除时销毁。有两种常见的解决方案:

  • 使用智能指针,它有一个可以删除它的析构函数,或者

  • 不要删除它;在大多数情况下,调用析构函数是没有道理的,如果你碰巧在其他静态对象的析构函数中使用了实例,就会遇到破坏顺序问题。

【讨论】:

    【解决方案4】:

    我想您实际上是指指向堆上对象的静态指针?

    这永远不会被自动删除,你必须自己做。大多数情况下,让程序结束并由操作系统进行清理就足够了,除非您使用内存检查工具或析构函数具有您需要的副作用。

    最简单的做法是使用智能指针,当没有人再引用它时,它会自动删除该对象。您可以在main 中保留指针的副本,如果有时没有人拥有副本,那么当main 退出时,该对象将被删除。

    【讨论】:

      【解决方案5】:

      在堆上分配的静态数据意味着一个静态的成员指针。如果是这种情况,您可以为其分配内存。

      【讨论】:

        【解决方案6】:

        我使用的这个解决方案是添加一个静态函数来释放内存。只是在关闭阶段的某个地方,调用者需要调用这个函数。我不确定这种做法是好是坏;至少它确实清理了堆上分配的内存。很高兴听到 cmets。

        class example {
           public:
              static void dealloThing() { delete ptr; }
              /**
               * You could have more elaborate arguments to set special version
               * of Thing, here not elaborating the details
               */
              static void setThing(Thing* tptr) { ptr = tptr; }
           private:
              static Thing* ptr;
        };
        
        ==== example.cpp ===
        Thing* example::ptr=new Example();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-02
          • 2013-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 2016-12-15
          • 2021-09-10
          相关资源
          最近更新 更多