Явно запретить выделение кучи в С++
У меня есть несколько классов, для которых я хотел бы явно запретить выделение кучи. Мне пришло в голову в этот уик-энд, что я могу просто объявить оператора новым частным (и не реализованным)... Конечно же, это приводит к ошибкам компиляции при попытке создать новый класс... Мой вопрос: есть ли еще что? Я что-то упустил или это хороший способ сделать то, что я хочу?
#include <stdio.h>
class NotOnTheHeap
{
public:
NotOnTheHeap() : foo( 0 )
{
}
private:
void *operator new( size_t );
void operator delete( void* );
void *operator new[]( size_t );
void operator delete[]( void* );
int foo;
};
class Heapable
{
private:
NotOnTheHeap noth;
};
int main( int argc, char* argv[] )
{
NotOnTheHeap noth;
Heapable* heapable = new Heapable;
return 0;
}
Ответы
Ответ 1
Зависит от того, что вы подразумеваете под "явно запрещенным распределением кучи".
Если вы просто хотите предотвратить прямое распределение в куче, то есть:
NotOnTheHeap *n = new NotOnTheHeap();
это достаточно хорошо. Но это не помешает, чтобы ваш объект существовал в куче в целом.
Например, это не помешает людям использовать std::vector <NotOnTheHeap>
, который будет выделять объекты из вашего класса в куче.
Это также не помешает людям использовать NotOnTheHeap
как переменную-член в другом классе, которая выделяется в куче.
Ответ 2
В основном вы достигнете того, что вы пытаетесь.
То, что ваше решение не покрывает, - это новое место, которое может быть или не быть в куче.
Ответ 3
Вы можете отключить копию или даже конструкцию по умолчанию, а оператор = и т.д. для более строгого сценария (некоторые случаи внедрения значений или использования контейнера).
Однако это выведет вас из некоторых полезных конструкций и заставит вас представить свою собственную семантику (что-то более заметное в VM impls, отсутствие/индукция аналогичного оператора и двусмысленные механизмы эквивалентности/равенства). Вероятно, вы также увидите несколько предупреждений о компиляторе, это не будет идти полным ходом, но если его утешение может иметь использование или два.
Ответ 4
Разве вы не можете сделать реализацию оператора new assert (0)?
Ответ 5
Почувствуйте эффективный С++ и более эффективный С++ Скотта Мейерса - он охватывает такие вещи. Каждый программист на С++ должен владеть и читать эти книги.