派生类中的成员new / delete重载有用吗?
我刚刚回答了关于缺少与展示位置相关的展示位置删除的问题。 原因似乎是根据对象的动态类型(与用于查找operator new
的类型相对应)调用operator delete
的方式。
安置new
对我有用。 当涉及到自定义分配时,可能有一个可重用的类,其中不同的实例管理不同的池。 单身是一种反模式,所有这一切。
我能理解制造new thing;
的便利性new thing;
在不跟踪分配器的情况下工作,但为类型层次结构的不同分支做事似乎相当复杂。
是否存在派生类从其基础使用不同分配器并且依赖于虚拟析构函数来查找正确的成员operator delete
的现实世界场景?
为免这是主观的,我会接受最合理的答案。 让我们不要对代码味道或“最好”的做事方式进行挑剔。
我以前真的用过这个! 这对于非统一的内存架构非常有用 - 这些平台具有非常小的非常快速的内存区域而没有操作系统等。
具体而言,设想例如具有少量TCM(紧密耦合的存储器;本质上,嵌入在SoC上的SRAM,例如具有1个周期的存取时间)的ARM芯片。
然后,我们在产品开发的很晚时候使用分析器结果 - 就在发货之前(假设这是一款流行掌上游戏系统的盒式存储器),以确定某些类将受益于更快的SRAM。
一个简单的成员operator new
现在可以将这个TCM用于派生类,这可能是有道理的:我们不能使用这个SRAM来获得整个类的层次结构,但是对于某些低实例化计数但是使用频繁的派生类,它变得简单而有效的优化。 在某些情况下,我们通过重定向某些分配的方式已经回到了2%-10%或更多的帧时间。
实际上我从来没有在派生类中使用new / delete重载,或者我曾经想过,但这个问题很有趣,我决定进行一些研究并给它一个镜头。 我找到了一对合适的参考文献:
ARM http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka14267.html
这个引用实际上有一个派生类的示例代码,它的基类重载了新的重载。
范德比尔特大学 http://www.vuse.vanderbilt.edu/~adamsja/Courses/CS251/Projects/4/memPool.pdf
此引用没有提供任何有关在派生类中重新载入新内容的明确材料,但是,它提到了为什么要重载新内容的一些有趣的原因。 这些原因包括:
现在基于这两个引用,我已经决定在派生类中重载新/删除可能有几个原因。 我的理由与我在VU演讲中列出的理由基本一致,但也基于ARM参考暗示我是嵌入式或专用场景。
再次,我从来没有找到一个理由,或者实际上实施了像你所提到的,但这些是我的想法,有一点调查。
是否存在派生类从其基础使用不同分配器并且依赖于虚拟析构函数来查找正确的成员operator delete
的现实世界场景?
我不确定你会考虑一个真实世界的场景,但我想到的一个明显的例子是一个植根于抽象基类的继承层次结构,其中有很多不同的(大小)派生类,其中很多是定期创建和销毁,而这些分配/释放需要速度。
您可能需要为这些派生类定制分配器,因为具有特定大小的内存blob的分配器可能非常快,您可能希望为每个派生类使用不同的分配器,因为它们的大小差别很大。
但是,我不能给你一个具体的例子,因为多年来我发现避免分配/释放的方式比加快它的速度更快,所以在近二十年的时间里,我很少超载特定于类的new
/ delete
。 (当然,正如我们在讨论复杂优化时通常所说的那样,“游戏”出现了,所以我们可以想象一个需要创建和销毁大量不同实体的游戏。)
上一篇: Are member new/delete overloads in a derived class ever useful?