Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在一个没有动态内存的世界里,我需要虚拟析构函数吗?_C++_Embedded_C++14_Virtual Destructor_Static Memory Allocation - Fatal编程技术网

C++ 在一个没有动态内存的世界里,我需要虚拟析构函数吗?

C++ 在一个没有动态内存的世界里,我需要虚拟析构函数吗?,c++,embedded,c++14,virtual-destructor,static-memory-allocation,C++,Embedded,C++14,Virtual Destructor,Static Memory Allocation,当对象可能从基类指针析构函数时,需要虚拟析构函数 考虑一个没有动态内存的程序,这在嵌入式系统中很常见。在这里,使用new或delete会触发链接器错误,因为未实现所需的底层分配器。因此,开发人员只在bss/数据部分使用静态分配的对象,或者通常在堆栈上使用自动分配的对象 在这样一个系统中,是否真的需要虚拟析构函数?假设没有人感到无聊,并在某个指针上手动调用析构函数 在我看来,静态和自动分配总是调用正确的析构函数。我错过什么了吗?有角落里的箱子吗?静态对象池与unique_ptr和自定义delete

当对象可能从基类指针析构函数时,需要虚拟析构函数

考虑一个没有动态内存的程序,这在嵌入式系统中很常见。在这里,使用new或delete会触发链接器错误,因为未实现所需的底层分配器。因此,开发人员只在bss/数据部分使用静态分配的对象,或者通常在堆栈上使用自动分配的对象


在这样一个系统中,是否真的需要虚拟析构函数?假设没有人感到无聊,并在某个指针上手动调用析构函数

在我看来,静态和自动分配总是调用正确的析构函数。我错过什么了吗?有角落里的箱子吗?静态对象池与unique_ptr和自定义deleter一起使用怎么样


假设没有人感到无聊,并在某个指针上手动调用析构函数

我认为你太快就排除了这种可能性。禁止动态分配的嵌入式/内存有限系统仍然可以创建具有动态存储持续时间的对象。注意:

alignas(T) char memory[sizeof(T)];
T *p = new(memory) T;  //Does not call global `new` allocator.

/*do stuff with `p`*/

p->~T();
没有理由禁止这样做。事实上,一些类型擦除的实现依赖于小对象优化。任何小型对象的实现都可以完全使用std::any对象本身中的内存来构造派生类。但它仍然需要调用该类型的析构函数,通常是通过基类指针。当然,有些实现不使用继承,但我的总体观点是,明确禁止手动调用析构函数会很奇怪


假设没有人感到无聊,并在某个指针上手动调用析构函数

我认为你太快就排除了这种可能性。禁止动态分配的嵌入式/内存有限系统仍然可以创建具有动态存储持续时间的对象。注意:

alignas(T) char memory[sizeof(T)];
T *p = new(memory) T;  //Does not call global `new` allocator.

/*do stuff with `p`*/

p->~T();

没有理由禁止这样做。事实上,一些类型擦除的实现依赖于小对象优化。任何小型对象的实现都可以完全使用std::any对象本身中的内存来构造派生类。但它仍然需要调用该类型的析构函数,通常是通过基类指针。当然,有些实现不使用继承,但我的总体观点是,明确禁止手动调用析构函数会很奇怪。

不,您没有遗漏任何内容。只有在通过基类指针调用派生析构函数时,才需要虚拟析构函数。否则,基本析构函数不需要是虚拟的。当然,将所有未设计为多态的类作为最终类。你未来的自我会感谢你的。这可能对释放除内存以外的资源有所帮助。使用自定义放置新建/删除也很常见。OTOH,现在模板通常更适合多态性工作。比如说,没有人觉得无聊,就在某个指针上手动调用析构函数。-这意味着什么?扩展Doug所说的,静态多态性模板,即编译时的多态性,可以完成动态多态性被过度使用的大部分工作。不,你没有遗漏任何东西。只有在通过基类指针调用派生析构函数时,才需要虚拟析构函数。否则,基本析构函数不需要是虚拟的。当然,将所有未设计为多态的类作为最终类。你未来的自我会感谢你的。这可能对释放除内存以外的资源有所帮助。使用自定义放置新建/删除也很常见。OTOH,现在模板通常更适合多态性工作。比如说,没有人觉得无聊,就在某个指针上手动调用析构函数。-这意味着什么?扩展Doug所说的,静态多态性模板,即编译时的多态性,可以完成动态多态性被过度使用的大部分工作。