C++在这方面与Java非常不同,因此以下是简要概述:
分配:为对象分配内存。
构造:准备使用对象。
析构:对象完成所有操作并解散自身。
释放:将内存归还给系统。
int main() {
int myint;
}
int main() {
int* mypointer;
mypointer = new int;
delete mypointer;
}
class myclass {
public:
myclass() {}
myclass(const myclass& rhs) {}
myclass& operator=(const myclass& rhs) {return *this}
~myclass() {}
};
当函数结束时,函数本身中的所有变量(我们称之为自动变量)都会调用其析构函数,然后自动释放。这意味着对于函数内部的本地对象,它们在函数结束的那一刻自动清理自己。
该规则也神奇地适用于类的成员。当销毁一个类的实例时,它的每个成员将自动被销毁。这意味着大多数析构函数为空。
如果手动分配了内存(使用new
关键字),则必须使用delete
关键字手动销毁和释放内存。当您调用delete
时,它将立即销毁(并deallocating)并且不会继续执行直到完成。如果您忘记了,它将永远不会被释放(尽管一些操作系统会在程序结束时处理它)。
由于人们常常犯错误,因此当需要使用动态对象时,“正确”的做法是:
int main() {
std::unique_ptr<myclass> myptr = 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
会执行,这意味着文件可能会一直保持锁定,直到程序结束。(虽然不太可能)