C++ 为什么在明确调用时,析构函数不会在模板指针上被调用?
在下面的测试用例中,我很困惑为什么析构函数似乎没有被调用,即使我显式地调用它。我注意到只有当模板类型是指针时才会发生这种情况 代码(内存泄漏,但我尝试尽可能地使用最小的示例) 运行示例:正在调用析构函数。这不是你想的那个破坏者。基本上,你有:C++ 为什么在明确调用时,析构函数不会在模板指针上被调用?,c++,templates,destructor,C++,Templates,Destructor,在下面的测试用例中,我很困惑为什么析构函数似乎没有被调用,即使我显式地调用它。我注意到只有当模板类型是指针时才会发生这种情况 代码(内存泄漏,但我尝试尽可能地使用最小的示例) 运行示例:正在调用析构函数。这不是你想的那个破坏者。基本上,你有: int main() { using T = A*; T* arr = new T[1]; arr[0]->~T(); } 但是T是A*,因此您调用的析构函数是指针析构函数-这很简单-而不是类的析构函数。您的Template
int main() {
using T = A*;
T* arr = new T[1];
arr[0]->~T();
}
但是T
是A*
,因此您调用的析构函数是指针析构函数-这很简单-而不是类的析构函数。您的TemplateTest pt
对象在任何时候都不实际创建A
的任何实例-仅创建A*
的实例 正在调用析构函数。这不是你想的那个破坏者。基本上,你有:
int main() {
using T = A*;
T* arr = new T[1];
arr[0]->~T();
}
但是
T
是A*
,因此您调用的析构函数是指针析构函数-这很简单-而不是类的析构函数。您的TemplateTest pt
对象在任何时候都不实际创建A
的任何实例-仅创建A*
的实例 你到底为什么要显式地调用析构函数?出于什么目的?它是std::vector实现的一个较小的测试用例,除非您使用的是placement new
,否则不建议这样显式调用析构函数(我敢说,这是一个bug)。我在代码的长格式版本中调用placement new。我把这个例子缩小了,以关注析构函数没有被调用的问题。在这个世界上,你为什么要显式地调用析构函数?出于什么目的?它是std::vector实现的一个较小的测试用例,除非您使用的是placement new
,否则不建议这样显式调用析构函数(我敢说,这是一个bug)。我在代码的长格式版本中调用placement new。我将示例缩小,以关注析构函数未被调用的问题。我更新了测试用例,以表明使用A*对象时,它仍然不会被调用。@JudeClake编辑使我的声明关于您没有创建A
的实例为false,但它不会改变其余答案。你永远不会调用的析构函数。。。只有A*
的析构函数。在上面的例子中我如何调用A*析构函数?“在上面的例子中我如何调用A*析构函数?”如果你在模仿std::vector,你可能不应该这样做。如果创建std::vector并将指针推送到它并将其删除,则不会删除指向它的对象。这涉及到如何管理内存的所有权,STL为此类情况提供了std::shared_ptr和std::unique_ptr。如果您坚持为指向对象调用dtor(假设您正在编写judeclarke::owner_vector),则需要专门化指针上的模板类并调用“delete”。(小心输入**tho)@jude我建议您在滚动自己的std::vector
之前,先阅读指针和值之间的差异?间接性是一个很难解决的问题,如果你不想在它上面绊倒很多的话,就需要掌握它。编译时代码生成是另一个困难的问题。当你掌握了两者都不容易出错时,一起做这两件事是很容易出错的。我更新了测试用例,以表明使用A*对象,它仍然不会被调用。@JudeClake编辑使我的声明关于你没有创建A
的实例为false,但它不会改变其余答案。你永远不会调用的析构函数。。。只有A*
的析构函数。在上面的例子中我如何调用A*析构函数?“在上面的例子中我如何调用A*析构函数?”如果你在模仿std::vector,你可能不应该这样做。如果创建std::vector并将指针推送到它并将其删除,则不会删除指向它的对象。这涉及到如何管理内存的所有权,STL为此类情况提供了std::shared_ptr和std::unique_ptr。如果您坚持为指向对象调用dtor(假设您正在编写judeclarke::owner_vector),则需要专门化指针上的模板类并调用“delete”。(小心输入**tho)@jude我建议您在滚动自己的std::vector
之前,先阅读指针和值之间的差异?间接性是一个很难解决的问题,如果你不想在它上面绊倒很多的话,就需要掌握它。编译时代码生成是另一个困难的问题。当你已经掌握了两者都不容易出错时,一起做这两件事。
int main() {
using T = A*;
T* arr = new T[1];
arr[0]->~T();
}