C+中的析构函数+;(与java相比)
到目前为止,我一直在用Java编写程序。所以,当我开始C++时,我脑海中出现的第一件事是如何破坏/删除/终结我不再需要的对象。 使用Java时,我通常将它们设置为C+中的析构函数+;(与java相比),java,c++,garbage-collection,Java,C++,Garbage Collection,到目前为止,我一直在用Java编写程序。所以,当我开始C++时,我脑海中出现的第一件事是如何破坏/删除/终结我不再需要的对象。 使用Java时,我通常将它们设置为null,因此垃圾收集器负责处理它。 不过,我不知道事情如何与C++相关联。我发现这篇文章解决了我的大部分问题。但仍有一些事情我不明白 1) 在Java中,有一种方法可以强制垃圾收集器立即清理(这并不总是有用的,因为它会在运行之前等待一些垃圾堆积起来)。有没有办法用C++来实现?< /P> 2) (C++)同样与上述相反,如何使对象处于
null
,因此垃圾收集器负责处理它。
不过,我不知道事情如何与C++相关联。我发现这篇文章解决了我的大部分问题。但仍有一些事情我不明白
1) 在Java中,有一种方法可以强制垃圾收集器立即清理(这并不总是有用的,因为它会在运行之前等待一些垃圾堆积起来)。有没有办法用C++来实现?< /P>
2) (C++)同样与上述相反,如何使对象处于“标记为删除”状态,并由程序决定何时清理它(如Java)
3) (C++)我是否应该强制barbage collector当场清洁(我很确定这不是正确的方法,但我只是想确定一下)
如果你能给出一个代码触发的小代码示例,我会很感激。C++中的< p>垃圾回收总是即时的。没有单独的垃圾收集器;删除对象时,它将立即在当前线程上删除。看起来是这样的:
MyObject* foo = new MyObject();
...
delete foo;
<>有可用的C++垃圾收集框架,也可以查看智能指针,这也是垃圾收集的一种形式。
请注意James在下面的评论--对象的析构函数和运算符delete总是立即调用,但内存是否立即可用取决于实现。1)如果对象处于自动存储中,则可以限制其范围:
{
X x;
//...
} //x gets destructed here
如果在动态存储中,则在完成后删除它们:
X* x = new X;
//...
delete x; //x gets destructed
2) 你不能(至少以干净的方式)。您必须指示C++何时删除对象,即使该指令由结束括号组成。(请参见第一个代码段)
3)C++中没有垃圾回收器。请参阅这两个片段。您要么必须显式删除对象(如果在动态存储中),要么在自动存储中自动删除对象(但不会被垃圾收集器删除)
值得研究的是智能指针(有很多实现),但这也不是垃圾收集器。它只是为您节省了管理内存的麻烦。但是它并不像java。< /p> C++中没有垃圾回收器。您应该自己编写和运行析构函数。在C++中,忘记运行析构函数是常见错误。
myclass *p = new myclass();
// do something
delete p;
如果为对象分配了new
,则应使用delete
将其删除。因此,new
调用构造函数,而delete
调用析构函数
myclass *p = new myclass();
// do something
delete p;
这称为动态对象分配
如果您的对象定义为“正常”,则当超出范围时,它将自动销毁
myclass a;
// do something
// will destructed when }
这称为自动对象分配
另外,在Java中,您也不需要分配空值,因为垃圾收集器的发明就是为了避免对象删除 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
};
当函数结束时,函数本身中的所有变量(我们称之为automatic)都会调用它们的析构函数,然后它们会自动释放。这意味着对于函数的局部对象,它们会在函数结束时自动清理自身。这也神奇地适用于一个类的成员。当它被销毁时,它的每个成员都将被自动销毁。这意味着大多数析构函数都是空的
如果您手动分配内容(使用new
关键字),则必须使用delete
关键字手动销毁和解除分配内容。当您调用delete
时,它会立即销毁(并取消分配),直到完成为止。如果您忘记了,它将永远不会被解除分配(尽管某些操作系统会在您的程序结束时解除分配)
由于人们会犯错误,因此在需要动态对象时,“正确”的做法是:
int main() {
std::unique_ptr<myclass> myptr = new myclass(); //allocate and construct
} //both the unique_ptr and the dynamic object are destroyed and deallocated
intmain(){
std::unique_ptr myptr=new myclass();//分配和构造
}//唯一的\u ptr和动态对象都被销毁和释放
而且unique炣ptr
足够智能,可以自动清理它所指向的内容,从而释放您更多的关注点
< C++之所以这样做是因为如果有一个对象“代码>代码< f/COD>”,它表示该文件,它可能对该文件有一个排他锁。在C++中,一旦代码“F>代码”被破坏,你可以立即创建一个使用相同文件的对象<代码> g <代码>。在Java中,不能保证终结器会运行,这意味着在程序结束之前,该文件可能会保持锁定状态。(不太可能,但可能)C++使用RAII(资源获取是初始化)编程习惯用法,没有什么比java中称为垃圾收集器的自动内存管理或Objective-C2中称为AutoZone的自动内存管理更好的了。因此,适当的实例清理很容易变得复杂。回答您的问题:
广告1:C++中没有GC,所以你必须手动删除你的对象或者使用引用计数技术或者更好的智能指针,这是C++ 11标准的一部分,但据我所知,它在任何C++编译器中都是不可用的。现在,您可以使用Boost库中的智能指针模板:。新的C++标准直接采用Boost实现,因此在不久的将来切换到新标准时不会有问题(MSVC 2012将实现C++ 11支持)。
广告2:没有