Disabling Allocation on the Free-store
It's possible to define a class whose objects may be created on the stack or static memory but not on the free-store. For this purpose, override global new and deleteby declaring them as non-public class members:
class AutoStatic
{
private:
void * operator new (size_t)
{return 0;} //dummy implementation
void operator delete (void*) {}
public:
//..
};
The compiler will use the overridden versions of new and deleteto allocate and destroy objects of this class. Because these operators are inaccessible, any attempt to allocate such objects on the free-store would cause compilation errors:
int main()
{
AutoStatic as; //fine
static AutoStatic as2; //fine
AutoStatic * p2= new AutoStatic; // error:
//'AutoStatic::operator new(unsigned int)'
//is not accessible
delete p2;//error:
//'AutoStatic::operator delete(void *)' is not
//accessible.
}
There is a loophole in this design, though. AutoStatic doesn't override the array versions of new and delete. If you wish to disable dynamic allocation of AutoStaticarrays, override these operators as well:
class AutoStatic
{
private:
//override global new[] and delete[]
void * operator new [](size_t);
void operator delete [] (void*);
//..
};
Design Refinements
In cross-platform code, you should provide dummy definitions for the overriding new and deletebecause some implementations may call them implicitly from constructors and destructors.
Notice, also, that in a class hierarchy, a derived class uses the overridden new and deleteof its base class, unless it declares its own overriding versions of these operators.
A Walk Down Memory Lane
Seasoned programmers can find ways to bypass the constraints that I've shown here. For example, one could use placement new to construct objects on a buffer that was allocated from the free-store. However, a bullet-proof design isn't the issue here. Rather, the aim is to protect your code from innocent human errors and to draw users' attention to the memory-usage policy of a given class. In this respect, making a destructor non-public is sufficient for disabling static and automatic objects. Similarly, declaring new and deleteas private or protected class members is also an effective mechanism for disabling free-store allocation.