Явно запретить выделение кучи в С++

У меня есть несколько классов, для которых я хотел бы явно запретить выделение кучи. Мне пришло в голову в этот уик-энд, что я могу просто объявить оператора новым частным (и не реализованным)... Конечно же, это приводит к ошибкам компиляции при попытке создать новый класс... Мой вопрос: есть ли еще что? Я что-то упустил или это хороший способ сделать то, что я хочу?

#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

Почувствуйте эффективный С++ и более эффективный С++ Скотта Мейерса - он охватывает такие вещи. Каждый программист на С++ должен владеть и читать эти книги.