Частный деструктор

Почему я могу создать объект класса с частным деструктором в свободном хранилище, но не в стеке?

Например, это незаконно:

class Foo
{
public:
   explicit Foo( int );
   static void delete_foo(Foo* foo ) { delete foo; }
private:
   int x;
   ~Foo();
   Foo( const Foo& );
   Foo& operator=(const Foo& );
};

int main()
{
   Foo * fooptr = new Foo(5); // legal
   Foo::delete_foo( fooptr ); // legal 
   Foo foo(5); // illegal
}

Ответы

Ответ 1

Когда вы создаете его в стеке, он должен быть уничтожен до возвращения функции. Предполагая, что данная функция не имеет доступа к деструктору, это не разрешено.

Когда вы создаете его в свободном хранилище, он остается для другого кода, который имеет доступ к деструктору, чтобы его уничтожить.

Функция-член класса с частным деструктором может создать экземпляр в стеке. Статическая функция-член может даже вызываться без предшествующего экземпляра. Вероятно, нет оснований писать такую ​​вещь.

Ответ 2

Потому что объект с автоматическим хранилищем * должен быть, ну, автоматически разрушен. Поэтому деструктор должен быть доступен для вызова; Если это не так, вы не можете использовать этот тип в автоматическом хранилище.

Напротив, вам удастся удалить его при динамическом распределении. Вы можете, конечно, не делать этого.

* Объекты здесь, на "типичных" платформах, обычно выделяются в стеке.

Ответ 3

Поскольку создание объекта в свободном хранилище не требует публичного деструктора, но его создание в стеке происходит потому, что объекты будут уничтожены при выходе из области видимости. Вы можете создать объект в свободном хранилище, но вы не можете его удалить, поэтому у вас будет утечка памяти, если объект или функция друга не уничтожат его.

Ответ 4

Вы можете создать его в стеке только в области, имеющей доступ к деструктору. Поэтому вы можете сделать это в функции друга или статической членной функции класса (или даже обычного члена класса).

Конец функции для локальной переменной отвечает за удаление, поэтому должен иметь возможность вызвать деструктор, хотя и неявно.

Вы можете создать его с новым из любого места, если у вас есть доступ к соответствующему конструктору.

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

Ответ 5

Потому что тогда вы можете обеспечить, чтобы объект всегда распределялся динамически, то есть с новым оператором. Для выполнения этой работы вам понадобится реализовать метод dispose(), который вызывает "удалить это" до его возврата. Это позволяет создавать методы финализации, которые вызываются до того, как объект или часть объекта будут уничтожены, и поэтому могут безопасно удалять или отключать экземпляры членов до того, как цепочка виртуальных деструкторов будет вызвана.