It's said that, as a good practice, when implementing one of the forms of the operator new
for a class, it is recommended that all the others forms also must be implemented. If don't, due to c++
not intuitive visibility rules, bad things can happen. What are these bad things and how do they happen? Can the not implemented forms get hidden?
I assume you're talking about overloading the global operator new
function versus a class-specific operator new
.
TL;DR: If you want to have fine-grained memory control, you may wish to consider using an Allocator paradigm, like the standard containers. The rules are complicated and error-prone.
The most common reason to implement all of them is due to the confusing calling contexts. Often, the class-specific new will be implemented in terms of the global operator. However, this is not required, so you can get surprised.
For example, let's say you wrote class A
and class B
and you want to control allocation. You write overrides for A
and 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);
}
};
A well-intentioned user of your code writes:
void *operator(size_t sz) {
return incompatible_allocator(sz);
}
If someone allocates your class with ::new A;
then the class-specific version is ignored. So all of a sudden, a different allocator is used. The programmer may not be careful, and calls delete. Since you are careful, you have also defined operator delete
. But now, your very_clever_allocator
doesn't know about this object. This will be a hard to diagnose bug.
This is not common, but since these rules are very complicated, it's usually easier to use an Allocator
. If you're just writing code to debug, this is OK for a one time thing.
More reading: https://eli.thegreenplace.net/2011/02/17/the-many-faces-of-operator-new-in-c