#include <iostream>
using namespace std;
class constructor {
public:
static int c, d;
constructor() {
c++;
}
~constructor() {
d++;
}
};
int constructor::c, constructor::d;
int main() {
constructor c;
cout<<constructor::c<<" "<<constructor::d;
return 0;
}
Output: 1 0
如果我显式调用析构函数,则输出为1 1
我想知道,为什么隐式调用析构函数时d
不增加?
答案 0 :(得分:3)
您要在调用c
的析构函数之前进行打印-它将在范围的末尾被调用。添加一个新块会产生预期的输出:
int main() {
{
constructor c;
}
cout<<constructor::c<<" "<<constructor::d;
}
答案 1 :(得分:1)
我想知道,为什么隐式调用析构函数时d不增加?
是的,但是到您输出constructor::d
时,它尚未被调用。将代码更改为
{
constructor c;
}
cout<<constructor::c<<" "<<constructor::d;
要查看析构函数调用:此代码在较小范围内构造c
,并在较小范围的末尾(这里:在}
处)对其进行分解。
答案 2 :(得分:1)
当您尝试打印c
成员时,变量d
的生命期尚未结束。该变量仍然有效并且在范围内。
如果您尝试例如
int main()
{
// Add a new nested scope
{
constructor c; // Construct object in nested scope
}
// Nested scope ended, so the life-time of c have ended and it has been destructed
cout<<constructor::c<<" "<<constructor::d;
}
然后应该增加析构函数计数器。
答案 3 :(得分:1)
在您的示例中未调用析构函数,因为该对象在当前作用域中仍然可用。在当前作用域中销毁对象有多种方法,下面是一个快速列表:
该对象将在块的结尾处被破坏。
{
constructor c;
}
cout << constructor::c << " " << constructor::d;
我们可以创建一个唯一的指针,然后调用reset()
方法来释放它。
auto uniquePtr = std::make_unique<constructor>();
uniquePtr.reset();
cout << constructor::c << " " << constructor::d;
我们还可以创建一个共享指针并reset()
。
auto sharedPtr = std::make_shared<constructor>();
sharedPtr.reset();
cout << constructor::c << " " << constructor::d;
在可能性列表中,C ++允许您直接调用析构函数。
constructor c;
c.~constructor();
cout << constructor::c << " " << constructor::d;