Как мы размещаем Phoenix Singleton по тому же адресу?C ++ - PullRequest
0 голосов
/ 30 мая 2018

код ниже иллюстрирует Phoenix Singleton , описанный в Книге Андрея Александреску Modern C ++ Design.

Singleton& Instance()
{
   if (!pInstance_)
   {
   // Check for dead reference
      if (destroyed_)
      {
         OnDeadReference();
      }
      else
      {
   // First call—initialize
         Create();
      }
   }
return pInstance_;
}

void Singleton::OnDeadReference()
{
// Obtain the shell of the destroyed singleton
   Create();
// Now pInstance_ points to the "ashes" of the singleton
// - the raw memory that the singleton was seated in.
// Create a new singleton at that address
   new(pInstance_) Singleton;
// Queue this new object's destruction
   atexit(KillPhoenixSingleton);
// Reset destroyed_ because we're back in business
   destroyed_ = false;
}

static void Create();
{

// Task: initialize pInstance_
   static Singleton theInstance;
   pInstance_ = &theInstance;
}

void Singleton::KillPhoenixSingleton()
{
// Make all ashes again
// - call the destructor by hand.
// It will set pInstance_ to zero and destroyed_ to true
   pInstance_->~Singleton();
}


virtual ~Singleton()
{
   pInstance_ = 0;
   destroyed_ = true;
}

Singleton* Singleton::pInstance_ = 0;
bool Singleton::destroyed_ = false;

Цитата из книги:

Давайте проанализируем поток событий.Во время выхода из приложения вызывается деструктор Синглтона.Деструктор сбрасывает указатель на ноль и устанавливает destroy_ в значение true.Теперь предположим, что некоторый глобальный объект пытается снова получить доступ к Singleton.Экземпляр вызывает OnDeadReference.OnDeadReference реанимирует Singleton и ставит в очередь вызов KillPhoenixSingleton, и Instance успешно возвращает ссылку на действительный объект Singleton.С этого момента цикл может повторяться.

Мой вопрос: если мы назначим указатель pInstance_ = 0 в деструкторе, чем он назначит локальную статическую ссылку, которая должна быть удалена этой точкой,как мы размещаем новый объект по адресу 0?Пожалуйста, скажите мне, что я что-то упустил.Если кто-то может объяснить мне поток, я был бы очень признателен.Спасибо

1 Ответ

0 голосов
/ 30 мая 2018

Название "Феникс" происходит от легендарной птицы, которая погибла, загорелась и родилась заново из пепла.

В этом случае да, Синглтон может умереть, деструктор бежит, pInstanceстановится nullptr, и он ушел - пока его не нужно оживить.Когда это происходит, Create делает pInstance ненулевым, прежде чем new (pInstance) Singeton воссоздает объект.

[править] Вы должны знать правила для времени жизни объекта и продолжительности хранения.Очевидно, что хранилище для объекта должно быть выделено до создания объекта, и хранилище не должно быть освобождено, пока объект не будет уничтожен.Промежуток между ними известен как продолжительность хранения .Теперь существует такая вещь, как статическая продолжительность хранения .Такое хранилище не восстанавливается до тех пор, пока программа не закроется, даже если объект в этом хранилище будет уничтожен.Переменные, определенные в области пространства имен («глобальные переменные») и переменные static, имеют статическую продолжительность хранения.

Следовательно, хранилище для theSingleton имеет статическую продолжительность хранения, и pInstance может указывать на это хранилище дажеесли объект есть destroyed.Обратите внимание, что сами переменные destroyed и pInstance также имеют статическую длительность хранения, поскольку являются глобальными.

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