Явно запретить выделение кучи в C ++ - PullRequest
15 голосов
/ 21 декабря 2009

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

#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;
}

Ответы [ 4 ]

11 голосов
/ 21 декабря 2009

Зависит от того, что вы имеете в виду под «явным запретом выделения кучи».

Если вы просто хотите предотвратить прямое распределение в куче, то есть ::1003*

NotOnTheHeap *n = new NotOnTheHeap();

это достаточно хорошо. Но это не помешает тому, что ваш объект вообще существует в куче.

Например, это не помешает людям использовать std::vector <NotOnTheHeap>, который будет распределять объекты из вашего класса в куче.

Это также не помешает людям использовать NotOnTheHeap в качестве переменной-члена в другом классе, который расположен в куче.

1 голос
/ 21 декабря 2009

Вы можете отключить копирование или даже конструкцию по умолчанию и оператор = и т. Д. Для более строгого сценария (в некоторых случаях встраивания значений или использования контейнера).

Тем не менее, это выведет вас из некоторых полезных конструкций и заставит вас ввести собственную семантику (что-то более заметное в терминах ВМ; отсутствие / индукция подобного оператора и неоднозначные механизмы эквивалентности / равенства). Скорее всего, вы также увидите несколько предупреждений компилятора, они не будут проходить до конца, но, если у вас есть какое-то утешение, они могут быть использованы один или два.

1 голос
/ 21 декабря 2009

Это в основном позволит добиться того, что вы пытаетесь.

То, что ваше решение не покрывает, является новым на месте, которое может быть или не быть в куче.

0 голосов
/ 21 декабря 2009

Разве вы не можете просто сделать реализацию оператора новой assert (0)?

...