是否有Java的析构函数?我似乎无法找到任何关于此的文档.如果没有,我怎样才能达到同样的效果?
为了使我的问题更具体,我正在编写一个处理数据的应用程序,并且规范说应该有一个"重置"按钮,使应用程序恢复到其原始的刚启动状态.但是,除非关闭应用程序或按下重置按钮,否则所有数据都必须为"实时".
作为一名C/C++程序员,我认为实现这一点非常简单.(因此我计划最后实现它.)我构建了我的程序,使得所有'可重置'对象都在同一个类中,这样我就可以在按下重置按钮时销毁所有'实时'对象.
我在想如果我所做的只是取消引用数据并等待垃圾收集器收集它们,如果我的用户反复输入数据并按下重置按钮,是否会出现内存泄漏?我也在想,因为Java作为一种语言非常成熟,应该有办法防止这种情况发生或优雅地解决这个问题.
class Package:
def __init__(self):
self.files = []
# ...
def __del__(self):
for file in self.files:
os.unlink(file)
Run Code Online (Sandbox Code Playgroud)
__del__(self)上面因AttributeError异常而失败.我理解Python在__del__()调用时不保证存在"全局变量"(在此上下文中的成员数据?).如果是这种情况并且这是异常的原因,我该如何确保对象正确破坏?
当用C++覆盖一个类(使用虚拟析构函数)时,我在继承类上再次将析构函数实现为虚拟,但是我是否需要调用基本析构函数?
如果是这样,我想它就是这样......
MyChildClass::~MyChildClass() // virtual in header
{
// Call to base destructor...
this->MyBaseClass::~MyBaseClass();
// Some destructing specific to MyChildClass
}
Run Code Online (Sandbox Code Playgroud)
我对吗?
大多数人都说永远不会从析构函数中抛出异常 - 这样做会导致未定义的行为.Stroustrup指出"向量析构函数显式地为每个元素调用析构函数.这意味着如果元素析构函数抛出,向量破坏失败......实际上没有好的方法来防止从析构函数抛出的异常,所以库如果元素析构函数抛出",则不保证"(来自附录E3.2).
这篇文章似乎另有说法 - 抛出析构函数或多或少都没问题.
所以我的问题是 - 如果从析构函数抛出会导致未定义的行为,那么如何处理析构函数期间发生的错误?
如果在清理操作期间发生错误,您是否只是忽略它?如果它是一个可能在堆栈中处理但在析构函数中不正确的错误,那么从析构函数中抛出异常是否有意义?
显然,这类错误很少见,但可能.
例如:
public class Person
{
public Person()
{
}
~Person()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我什么时候应该手动创建析构函数?什么时候需要创建析构函数?
我有一个类(A),它为其中一个字段使用堆内存分配.A类被实例化并作为指针字段存储在另一个类(B)中.
当我完成对象B时,我调用delete,我假设调用了析构函数...但是这也调用了A类中的析构函数吗?
从答案中,我接受了(请编辑,如果不正确):
class A B的实例调用B :: ~B();class Bdelete 应该显式地将delete所有堆分配的成员变量A;写错是不对的:
class A {
public:
virtual ~A() = 0;
};
Run Code Online (Sandbox Code Playgroud)
对于抽象基类?
至少在MSVC中编译......它会在运行时崩溃吗?
我理解虚拟析构函数的必要性.但为什么我们需要纯虚拟析构函数?在其中一篇C++文章中,作者提到我们在创建类抽象时使用纯虚析构函数.
但是我们可以通过将任何成员函数设置为纯虚拟来使类抽象化.
所以我的问题是
我们什么时候才能真正使析构函数变为虚拟?任何人都能给出一个很好的实时例子吗?
当我们创建抽象类时,将析构函数设置为纯虚拟是一种很好的做法吗?如果是..那为什么?
这可能是一个基本问题,可能已经被问过(比方说,这里); 但我还是不明白.所以,让我问一下.
考虑以下C++类:
class Obj{
char* str;
public:
Obj(char* s){
str = s;
cout << str;
}
~Obj(){
cout << "Done!\n";
delete str; // See the comment of "Loki Astari" below on why this line of code is bad practice
}
};
Run Code Online (Sandbox Code Playgroud)
以下代码片段之间的区别是什么:
Obj o1 ("Hi\n");
Run Code Online (Sandbox Code Playgroud)
和
Obj* o2 = new Obj("Hi\n");
Run Code Online (Sandbox Code Playgroud)
为什么前者调用析构函数,但后者不调用(没有显式调用delete)?
哪一个更受欢迎?
destructor ×10
c++ ×7
pure-virtual ×2
base-class ×1
c# ×1
constructor ×1
exception ×1
java ×1
new-operator ×1
polymorphism ×1
private ×1
python ×1
raii ×1