string * str=new string;
delete str;
当我删除指向一个对象的“str”时,是否会调用两个析构函数——一个用于指针本身,一个用于它指向的对象?
指针的析构函数会做什么?
delete
只是导致给定指针指向的对象被销毁(在这种情况下,string
对象。指针本身,由 表示str
,具有自动存储持续时间,并且在超出范围时将被销毁,就像任何其他局部变量一样。
但是请注意,非类类型没有析构函数。因此,即使您使用delete
非类类型,也不会调用析构函数,但是当指针超出范围时,它会像任何其他自动变量一样被销毁(意味着指针刚刚到达其生命周期的结尾,尽管指针指向的内存在您使用显式解除分配之前delete
不会被解除分配。)。
析构函数的概念只适用于对象(即用class
or定义的实体struct
),而不适用于普通类型,就像指针一样。指针就像int
变量一样存在。
它自己的指针不会被delete
语句破坏。但作为任何范围变量,它在范围结束时被销毁。
例子:
void Function()
{
string * str=new string;
delete str; // <-- here the string is destructed
} // <-- here the pointer is "destructed", which is mean it's memory freed from the stuck but no actual destruction function is called..
原始指针的析构函数,例如您的示例std::string*
,是微不足道的(就像其他原始类型的析构函数:int
,double
等)
智能指针类具有重要的析构函数,可以执行诸如释放资源、调整引用计数等操作。
当我删除指向一个对象的“str”时,是否会调用两个析构函数——一个用于指针本身,一个用于它指向的对象?
不delete
,需要一个指针参数。它销毁指向的对象(使用它的析构函数,如果它有一个,否则什么都不做),并释放指向的内存。您必须以前曾用于new
分配内存并在那里创建对象。
指针本身不受影响;但它不再指向一个有效的对象,所以你不能对它做任何事情。这有时被称为“悬空指针”。
指针的析构函数会做什么?
没有什么。只有类类型有析构函数。
我喜欢你从每个类型都有一个析构函数的概念中得到的简化。这样,您就不会对显式销毁存储值的模板产生心理故障,即使该存储值的类型是一个int
或指针:
template <class T> struct wrapper {
unsigned char data[sizeof(T)];
wrapper(T t) { ptr = new (data) T; }
~wrapper() { (T*)&data->~T(); } // ignore possible alignment problem
wrapper<int> i(3);
但是,int
s 和指针的析构函数完全是微不足道的:它们什么都不做,也没有地方可以看到析构函数的定义,因为定义不存在。所以说他们没有析构函数也是合理的。
无论哪种方式,当指针超出范围时,它就会消失;没有特殊的代码运行。