运营商新实施可见性问题

Operator new implementation visibility issue

据说,作为一种好的做法,当为 class 实现运算符 new 的一种形式时,建议也必须实现所有其他形式。如果不这样做,由于 c++ 不直观的可见性规则,可能会发生不好的事情。这些坏事是什么,它们是如何发生的?未实现的表单可以隐藏吗?

我假设您是在谈论重载全局运算符 new 函数与 class 特定的 operator new.

TL;DR:如果您想要细粒度的内存控制,您可能希望考虑使用分配器范例,如标准容器。规则复杂,容易出错

实现所有这些的最常见原因是调用上下文混乱。通常,特定于 class 的 new 将根据全局运算符来实现。然而,这不是必需的,所以你会感到惊讶。

例如,假设您编写了 class Aclass B 并且您想要控制分配。您为 AB.

编写覆盖
void *very_clever_allocator(size_t sz);

class A {
    void* operator new(size_t sz) {
        return very_clever_allocator(sz);
    }
};

class B {
    void* operator new(size_t sz) {
        return very_clever_allocator(sz);
    }
};

您的代码的善意用户写道:

void *operator(size_t sz) {
    return incompatible_allocator(sz);
}

如果有人将您的 class 分配给 ::new A;,则 class 特定版本将被忽略。所以突然之间,使用了一个不同的分配器。程序员可能不小心,调用了delete。既然你细心,你也定义了operator delete。但是现在,您的 very_clever_allocator 不知道这个对象。这将是一个很难诊断的错误。

这并不常见,但由于这些规则非常复杂,通常使用 Allocator 更容易。如果您只是编写用于调试的代码,这一次没问题。

更多阅读: https://eli.thegreenplace.net/2011/02/17/the-many-faces-of-operator-new-in-c