不要在任何实现中使用,只是为了理解我试图使用对象和另一个*
来对象显式调用析构函数。
CODE
#include<iostream>
using namespace std;
class A{
public :
A(){
cout<<"\nConstructor called ";
}
~A()
{
cout<<"\nDestructor called ";
}
};
int main()
{
A obj,*obj1;
obj1->~A();
obj.~A();
return 0;
}
的输出
现在的问题是,我无法理解为什么析构函数被调用三次
即使obj1
尚未指向任何对象
请注意,我知道最后两个析构函数调用是:
obj.~A()
; obj
的范围。我正在使用DevC++ 5.5.1
答案 0 :(得分:4)
您的代码仅适用于侥幸。
int main()
{
A obj,*obj1;
obj1->~A(); // (1) Bad reference that works
obj.~A(); // (2) Explicit call to destructor
return 0;
} // (3) obj's destructor is called when obj goes out of scope
答案 1 :(得分:3)
obj1->~A();
您取消引用尚未初始化的指针obj1
。这是未定义的行为。
在这种情况下,任何事情都可能发生,没有任何保证。
答案 2 :(得分:1)
它被调用三次,两次显式,一次超出范围。
第一个显式调用无效,因为指针未初始化(这是未定义的行为)。在你的情况下,似乎无论如何都调用了析构函数,并且因为它没有使用this
,所以没有任何不好的出现。 C ++标准中没有任何内容表明对未初始化指针的方法调用被忽略了!
通常,不应该多次调用对象的析构函数(显式或其他);但是,有明确的有效案例。考虑:
{
alignas(alignof(A)) char data[sizeof(A)]; // Not an A object, so no
// call to dtor at scope end
A* ptr = new (data) A();
ptr->~A(); // object is now destructed but memory in `data` can be reused
}
答案 3 :(得分:0)
析构函数被调用3次的问题实际上非常简单。
在C ++中,堆栈上构造的对象在超出范围时会自动销毁。而必须明确删除用new分配的对象。
class MyClass
{
public:
int Value;
MyClass(int n) : Value(n) // initialize Value with n
{
cout << "MyClass::ctor(" << Value << ")" << endl;
}
~MyClass()
{
cout << "MyClass::dtor(" << Value << ")" << endl;
}
};
int main()
{
{
MyClass a(10); // create a local object
MyClass* b = new MyClass(20); // create a dynamically allocated object
delete b; // free dynamic memory and call destructor
} // a goes out of scope and destructor is automatically invoked
return 0;
}
所以这还没有真正回答你的问题。简单地说,没有办法避免自动销毁本地对象。解决方法是 Cameron 使用本地缓冲区和新位置的示例:
MyClass* a = new (buffer) MyClass(10); // use placement new on a sufficient buffer
a->~MyClass(); // explicitly call destructor
如果您必须拥有本地显式对象,那么您始终可以跟踪您的对象是否确实有任何要销毁的内容:
class MyClass2
{
public:
MyClass* Resource; // some resource we are managing
MyClass2() : Resource(nullptr) {}
MyClass2(int n) : Resource(new MyClass(n)) {}
~MyClass2()
{
if (Resource) // do we have anything to "destroy"?
{
delete Resource; // call destructor, free memory
Resource = nullptr; // ensure the resource is "destroyed" only once
}
}
};
所以实际上,如果确实有“破坏”的东西,它只会调用析构函数的“有用”部分。