这个问题源于我想了解智能指针的动机,智能指针是围绕指针构造一个包装类,以便添加自定义析构函数。指针(还有整型、布尔型、双精度浮点型等)没有析构函数吗?
从技术角度来说,非类类型(在普通语言中通常称为“原始类型”)没有析构函数。
C++标准仅在类的上下文中讨论真正的析构函数,请参见C++标准中的[class.dtor]。除此之外,C++还允许使用相同的表示法在非类对象上调用析构函数,即以下代码是有效的:
void foo(int z) {
using T = int;
z.~T();
}
这被称为“伪析构函数”,其存在仅是为了允许编写通用模板代码,以相同的方式处理类和非类类型。该调用完全不起作用。此语法在C++标准中的[expr.prim.id]中定义。
基本类型(及其复合类型)具有平凡析构函数。这些函数不做任何事情,并且具有特殊措辞,使它们在某些情况下可以完全跳过。
然而,这与C++为什么有智能指针是无关的。原始指针是非所有权的:它指向另一个对象,但不影响其生命周期。另一方面,智能指针拥有(或共享所有权),将其所指对象的生命周期绑定到自己的生命周期中。这就是在内部实现的,除其他特殊函数外,还有它们的析构函数。
除了迄今为止在这里给出的答案,自从C++20以来,在非类对象上进行的伪析构函数调用将始终结束其生命周期。因此,在调用后访问对象的值将具有未定义的行为。然而,这并不意味着编译器必须为这样的调用发出任何代码。它仍然有效地什么也不做。
delete
- 如果程序的另一部分也有对同一对象的指针呢?malloc
的内存,关闭文件,释放锁定等。析构函数用于释放一个对象所使用的资源。
对于指针,如果你没有从堆上分配新内存,则不需要使用delete。
C和C++有两种变量存储方式:栈和堆。
栈是静态内存,编译器会自动处理。堆是动态内存,如果使用堆,则必须自己处理。
当进行基本类型声明时,变量的栈内存将被分配。
当使用new
声明对象时,该对象存储在堆上,使用完毕后必须将其删除,否则就会出现内存泄漏。
基本上,只有在使用new
时才需要使用delete
。
C++
不称之为堆栈或堆,然而就语言而言,这些只是实现细节。 - drescherjm