【发布时间】:2017-11-19 21:46:50
【问题描述】:
据说,作为一种好的做法,在为一个类实现运算符new的一种形式时,建议所有其他形式也必须实现。如果不这样做,由于c++ 不直观的可见性规则,可能会发生不好的事情。这些坏事是什么,它们是如何发生的?未实现的表单可以隐藏吗?
【问题讨论】:
标签: c++ operator-overloading new-operator
据说,作为一种好的做法,在为一个类实现运算符new的一种形式时,建议所有其他形式也必须实现。如果不这样做,由于c++ 不直观的可见性规则,可能会发生不好的事情。这些坏事是什么,它们是如何发生的?未实现的表单可以隐藏吗?
【问题讨论】:
标签: c++ operator-overloading new-operator
我假设您正在谈论重载全局运算符 new 函数与特定于类的 operator new。
TL;DR:如果您想要进行细粒度的内存控制,您可能希望考虑使用分配器范例,例如标准容器。规则复杂且容易出错。
实现所有这些的最常见原因是由于调用上下文令人困惑。通常,特定于类的 new 将根据全局运算符来实现。但是,这不是必需的,因此您可能会感到惊讶。
例如,假设您编写了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
【讨论】: