C++ 派生类中的成员new/delete重载有用吗?

C++ 派生类中的成员new/delete重载有用吗?,c++,inheritance,operator-overloading,new-operator,C++,Inheritance,Operator Overloading,New Operator,我刚才回答的是缺少与placement new相对应的placement delete。原因似乎是根据对象的动态类型调用操作符delete的方式(对应于用于查找操作符new的类型) Placementnew对我很有用。当谈到自定义分配时,可能存在一个可重用类,其中不同的实例管理不同的池。单身是一种反模式的行为 我能理解制作新事物的便利性在不跟踪分配器的情况下工作,但为类型层次结构的不同分支执行操作似乎非常复杂 是否存在这样一种现实场景:派生类使用与其基不同的分配器,并依赖虚拟析构函数来查找正确的

我刚才回答的是缺少与placement new相对应的placement delete。原因似乎是根据对象的动态类型调用
操作符delete
的方式(对应于用于查找
操作符new
的类型)

Placement
new
对我很有用。当谈到自定义分配时,可能存在一个可重用类,其中不同的实例管理不同的池。单身是一种反模式的行为

我能理解制作
新事物的便利性在不跟踪分配器的情况下工作,但为类型层次结构的不同分支执行操作似乎非常复杂

是否存在这样一种现实场景:派生类使用与其基不同的分配器,并依赖虚拟析构函数来查找正确的成员
运算符delete

为了避免这是主观的,我会接受最合理的答案。让我们不要在代码气味或“最佳”做事方式上争论不休

是否存在这样一种现实场景:派生类使用与其基不同的分配器,并依赖虚拟析构函数来查找正确的成员
运算符delete

我不确定你会考虑一个真实的场景,但是我脑海中出现的一个明显的例子是一个继承层次结构,它根植于一个抽象的基类中,在很大程度上不同于(在大小上)派生类,其中很多都是规则地创建和破坏的,而这些分配/分发则需要速度。p> 您可能需要为这些派生类使用自定义分配器,因为特定大小的内存块的分配器可能非常快,并且您可能需要为每个派生类使用不同的分配器,因为它们的大小非常不同


不过,我不能给你们一个具体的例子,因为这些年来我发现避免分配/解除分配比加快分配/解除分配更有效,所以近二十年来我很少重载特定于类的
new
/
delete
。(当然,当我们谈论复杂的优化时,通常会出现“游戏”,因此我们可以想象一个需要创建和销毁大量不同实体的游戏。)

我实际上从未在派生类中使用过new/delete重载,也从未想过,但这个问题很有意思,我决定做一些研究并尝试一下。我找到了一些合适的参考资料:

手臂

这个引用实际上有一个派生类重载其基类重载new的示例代码

范德比尔特大学

该引用没有提供任何关于在派生类中重载new的明确内容,但是,它提到了一些有趣的原因,比如为什么重载new。这些原因包括:

  • 补偿默认分配器中的次优对齐
  • 将相关对象聚集在一起
  • 获取非常规行为,例如用零覆盖内存,以提高应用程序数据的安全性
现在基于这两个引用,我决定在派生类中重载new/delete可能有一些原因。我的理由基本上与我在VU演示中列出的理由一致,但似乎也与ARM参考相关,这对我来说意味着一个嵌入式或专用场景

  • 嵌入式系统通常在硬件级别非常定制,但是在软件级别的标准化意义上是常见的。我可以看到一种情况,根据配置设置/硬件带,在运行时选择了某种类型的对象(派生类),因为它需要以特定的方式或特定的位置分配内存
  • 集群似乎是合理的,因为我可以设想这样一种场景:在高级“工作流”中,某些对象被视为相同的对象,但在处理时,这些对象的不同类型被处理得非常不同。对于流程密集型任务(即搜索、排序、优先级排序等),将特定类型的对象彼此靠近可能是有益的
  • 最后一点很有趣,因为我可以看到某些情况下,分配取决于所存储信息的安全分类

同样,我还没有找到一个原因,也没有实际实现您提到的东西,但经过一点调查后,这些是我的想法。

一个成员
操作符new
/
delete
可能有助于从基类中删除不需要的自定义分配,例如,如果基类不打算扩展的话。但是基对象可能需要一个虚拟析构函数,或者基对象永远不能成为
delete
的主题

实际上,
操作符delete
的虚拟析构函数调度是独立于重载的。该特性的存在可能是为了支持多重继承,而动态查找正确的成员
操作符delete
只是一个副作用

规则很简单,大多数派生对象的虚拟析构函数调用
操作符delete
。主要原因是传递正确的最派生指针和大小。上下文还使程序能够动态地找到正确的释放函数,这只是一个令人高兴的副作用

因此,对于动态
delete
dispatch,可能有也可能没有一个有用的应用程序,但绝对没有一个专门的机制使其工作

:

struct pad{
int x;
虚拟~pad(){}
};
结构b{
int x;
};
结构vb{
int x;
虚拟~vb(){}
};
结构d:pad,b,vb{};
void运算符删除(void*p){

std::cout我过去确实用过这个!它是
struct pad {
    int x;

    virtual ~pad() {}
};

struct b {
    int x;
};

struct vb {
    int x;

    virtual ~vb() {}
};

struct d : pad, b, vb {};

void operator delete( void *p ) {
    std::cout << "free " << p << '\n';
}

int main() {
    std::cout << "With virtual destructor:\n";
    d *p = new d;
    std::cout << "allocate " << p << ", delete " << static_cast< vb * >( p ) << '\n';
    delete static_cast< vb * >( p );

    std::cout << "With plain destructor:\n";
    p = new d;
    std::cout << "allocate " << p << ", delete " << static_cast< b * >( p ) << '\n';
    delete static_cast< b * >( p );
}