C++ 删除静态数据
Posted
技术标签:
【中文标题】C++ 删除静态数据【英文标题】:C++ Deleting Static Data 【发布时间】:2011-10-14 13:37:34 【问题描述】:如果我有一个包含在堆上分配的私有静态数据且永不更改的类,我应该在什么时候(如果有的话)删除它?
据我了解,永远不会构造一个类本身(因为类不是 C++ 中的第一类对象),那么就没有析构函数来删除其中的静态数据吗?我是 C++ 新手,如果我对 C++ 的理解存在根本性缺陷或者答案很明显,我很抱歉! 在此先感谢,呃。
【问题讨论】:
"类不是 C++ 中的第一类对象" 现在那是一个新对象... 天哪,看看我的基本缺陷位 不是批评,只是观察。 ;-] @ildjam:我不确定类是 C++ 中的第一类对象。实际上,它们不能被视为对象,即创建、修改等。它们只能被实例化。类是其他语言中的第一类对象:ruby、python、javascript、objc... @ildjarn:在理论上的 CompSci 中,“是类型对象本身”的问题是一个很好理解的问题。在 C++ 中这个问题的答案是否定的。最接近 C++ 的是typeid()
/ std::type_info
,它是一个对象描述一个类型。
【参考方案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();
【讨论】:
以上是关于C++ 删除静态数据的主要内容,如果未能解决你的问题,请参考以下文章