C++中的析构函数(与Java相比)
C++中的析构函数(与Java相比)
迄今为止,我一直在使用Java编写程序。因此,当我开始使用C ++时,我首先想到的是如何销毁/删除/完成我不再需要的对象。
在Java中,我通常将它们设置为null
,因此垃圾收集器可以处理它。
但是,我不知道C ++的情况。我发现了这篇文章http://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B解决了我大部分的问题。但还有一些我不理解的事情。
1) 在Java中,有一种方法可以强制垃圾收集器立即清除(这通常不太有用,因为它会等待一些垃圾堆积,然后再运行)。是否有一种方法可以在C ++中做到这一点?
2) (C ++)也与上述相反,我如何使对象处于“标记为删除”的状态,程序决定何时清除它(就像Java一样)?
3) (C ++)我应该强制垃圾收集器立即清除吗(我非常确定这不是正确的方法,但我只是问问以确保)?
如果您能提供一个小的代码示例来触发哪些代码,我会非常感激。
C++ 在这个领域与 Java 有很大的不同,以下是简要概述:
分配:为对象分配内存。
构造:准备使用该对象。
析构:对象“完成”所有工作并分解自身。
释放:将内存归还给系统。
int main() { int myint; //automatic int object is allocated and constructed //stuff } // when main ends, automatic int object is destroyed and deallocated int main() { int* mypointer; //automatic pointer object is allocated and constructed mypointer = new int; //dynamic int object is allocated and constructed //stuff delete mypointer; //dynamic int object is destroyed and deallocated } // when main ends, automatic pointer object is destroyed and deallocated // note: Pointers to _not_ delete the object they point to. class myclass { //members public: myclass() {} //this is the default constructor myclass(const myclass& rhs) {} //this is the copy constructor myclass& operator=(const myclass& rhs) {return *this} //this is the assignment operator ~myclass() {} //this is the destructor };
当函数结束时,函数本身中的所有变量(我们称为自动变量)都会调用它们的析构函数,然后它们会被自动释放。这意味着对于函数本地对象,它们会在函数结束时自动进行清理。这也神奇地适用于类的成员。当对象被销毁时,它的每个成员都将自动被销毁。这意味着大多数析构函数是空的。
如果您手动分配东西(使用 new
关键字),则必须使用 delete
关键字手动销毁和释放。当调用 delete
时,它会立即销毁(和释放),并且在完成之前不会继续。如果您忘记,则它永远不会被释放(虽然有些操作系统会在程序结束时释放它)。
由于人们会犯错误,使用动态对象时“正确”的做法是:
int main() { std::unique_ptrmyptr = new myclass(); //allocate and construct } //both the unique_ptr and the dynamic object are destroyed and deallocated
unique_ptr
足够智能,可以自动清理它所指向的东西,从而使您摆脱更大的问题。
C++ 之所以这样做是因为如果您有代表该文件的对象 F
,它可能对该文件具有独占锁定。在 C++ 中,一旦销毁 F
,您就可以立即创建使用相同文件的对象 G
。在 Java 中,不能保证 finalizer
将会运行,这意味着该文件可能会一直锁定直到程序结束。(虽然不太可能,但有可能)
1)如果你的对象在自动存储中,你可以限制它们的范围:
{ X x; //... } //x gets destructed here
如果在动态存储中,你在完成后要删除它们:
X* x = new X; //... delete x; //x gets destructed
2)你无法(至少没有一种干净的方法)。即使该指令由一个结束括号组成,你仍必须指示C++何时删除你的对象。 (请参见第一段代码)
3)C++中没有垃圾回收器。请参见两个代码片段。如果在自动存储中,你要么必须显式删除对象(如果在动态存储中),要么它们将自动删除(但不会由垃圾回收器进行)。
值得探索的是智能指针(有很多实现),但它也不是垃圾回收器。它仅仅省去了内存管理的麻烦。但它完全不像Java。