C ++如何确保为堆栈分配的对象调用析构函数?当我按如下方式分配动态内存时,析构函数(或指向它的指针)会发生什么:
class MyClass {
public:
~MyClass()
{
std::cout<<"Destructor called."<<std::endl;
}
MyClass()
{
std::cout<<"Constructor called."<<std::endl;
}
};
....................................................................
//Limit scope for example
{
MyClass instance;
}
构造函数和析构函数都被调用。这是怎么回事?
答案 0 :(得分:7)
编译器在适当的位置插入对对象的析构函数的调用。
答案 1 :(得分:4)
你不会想知道为什么这个
{
int i;
}
自动创建并销毁i
,是吗? C ++做了很多工作,允许您创建行为类似于内置类型的类型。就像内置类型一样,在C ++中(除了在Java或C#之外),这个
{
MyClass instance;
}
不只是定义可能绑定到null
或某个实际对象的引用。它创建一个实际的对象。
对象创建分为两步:首先(在进入范围时)提供原始内存。然后(当遇到对象定义时)调用构造函数。对于内置类型,不会调用构造函数。如果不初始化内置变量,则它具有随机值。 (实际上它就是步骤#1中提供的内存中的位模式。)对象删除也有两个步骤:首先,调用析构函数(同样,不是内置函数),然后返回内存运行时系统。
(请注意,为堆栈变量提供和删除内存通常与导入/递减寄存器一样便宜。)
答案 2 :(得分:3)
创建变量后立即调用构造函数。对于析构函数,编译器在作用域的末尾发出代码来调用析构函数。要想到这一点,请尝试使用'goto'或switch / case结构过早退出作用域,并观察编译器是否抱怨。
答案 3 :(得分:3)
是的,调用构造函数和析构函数。更重要的是:
{
MyClass instance;
throw "exception";
}
在这个例子中,也调用了析构函数。这就是为什么我总是喜欢在堆栈上分配我的对象(或者至少用堆栈分配的监护人包装动态分配)。
答案 4 :(得分:1)
调用构造函数是因为您正在创建一个对象。调用析构函数是因为您清理了该对象。请记住,在C ++中,当堆栈范围消失时,堆栈上声明的对象会自动清除。
答案 5 :(得分:0)
嗯,它没有在构造函数之后调用析构函数 它在即将终止程序时调用它。
int main() {
MyClass obj;
cout<<"testing....1"<<endl;
cout<<"testing....2"<<endl;
return 0;
}
ans:
Constructor called.
testing....1
testing....2
Destructor called.