据说,作为一种好的做法,当为一个类实现一个运算符new
的形式时,建议所有其他形式也必须实现。如果不这样做,由于c++
不直观的可见性规则,可能会发生不好的事情。这些坏事是什么?它们是如何发生的?可以隐藏未实现的表单吗?
答案 0 :(得分:1)
我假设您正在谈论重载全局运算符new
函数而不是特定于类的operator new
。
TL; DR:如果你想要细粒度的内存控制,你可能希望考虑使用Allocator范例,比如标准容器。这些规则很复杂且容易出错。
实现所有这些的最常见原因是由于令人困惑的调用上下文。通常,特定类别的新的将根据全球运营商的方式实施。但是,这不是必需的,所以你会感到惊讶。
例如,我们假设你写了class A
和class B
并想要控制分配。您为A
和B
撰写了替代。
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);
}
如果有人使用::new A;
分配您的班级,则会忽略特定于班级的版本。所以突然间,使用了不同的分配器。程序员可能不小心,并调用delete。由于您很小心,因此您还定义了operator delete
。但现在,您的very_clever_allocator
并不了解此对象。这将是一个难以诊断的错误。
这种情况并不常见,但由于这些规则非常复杂,因此使用Allocator
通常会更容易。如果你只是编写代码进行调试,这对于一次性事情来说是可以的。
更多阅读: https://eli.thegreenplace.net/2011/02/17/the-many-faces-of-operator-new-in-c