2013-10-08 4 views
1

Недавно меня спросили о шаблоне проектирования singleton в C++. Я не знал точно, что он делает или когда это требуется, поэтому я попытался найти его. Я нашел много ответов в основном на stackoverlow, но мне было трудно понять код, упомянутый в этих вопросах и ответах. Я знаю следующее свойство, которое синглтон должен удовлетворять, исправьте меня, если я ошибаюсь.Объяснение синглтонного кода C++

It is used when we need to make one and only one instance of a class. 

В этой связи возникает следующий вопрос, на мой взгляд

Does this mean that it can be created only once or does this mean that it can be 
created many times but at a time only one copy can exist? 

Сейчас подходит к реализации. скопирована из here

class S 
{ 
    public: 
     static S& getInstance() 
     { 
      static S instance; // Guaranteed to be destroyed. 
           // Instantiated on first use. 
      return instance; 
     } 
    private: 
     S() {};     // Constructor? (the {} brackets) are needed here. 
     // Don't forget to declare these two. You want to make sure they 
     // are inaccessible otherwise you may accidentally get copies of 
     // your singleton appearing. 
     S(S const&);    // Don't Implement 
     void operator=(S const&); // Don't implement 
}; 

Пожалуйста, объясните:

  1. Почему мы должны сделать функцию getinstace() статический?
  2. Зачем нам S (S const &); конструктор?
  3. Что делает оператор void = (S const &); делать?
  4. Почему мы не реализовали последние две функции?
  5. Зачем нам гарантированное уничтожение этого экземпляра (как указано в коде)?

ответ

3

1.Why мы должны сделать функцию getinstace() статический?

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

То есть с момента его статики вы можете написать:

S::getinstance().blah(); 

Если бы не было статичным вы должны были бы написать

S& s_instance = .... 
s_instance.getInstance().blah(); 

Но так как у вас уже есть экземпляр вам не нужно для звонка getInstance. И как вы получили этот экземпляр, если единственный способ получить экземпляр - через getInstance?

2.Why нам нужен S (S сопзЬ &); конструктор?

У вас нет. Его намеренно частные и не реализованы, поэтому его вызов вызовет ошибку. Если бы это было явно не сделано приватным и не реализован компилятор создаст конструктор по умолчанию общественного копирования для вас ... Это означало бы, люди могли бы написать

S scopy(S::getInstance()); 

и они в конечном итоге с новым экземпляром S - нарушение синтаксической семантики.

3.What делает недействительными оператора = (S сопзЬ &); делать?

То же, что и 2. Не реализовано и не является частным, поэтому его вызов вызовет ошибку. Опять же, если вы не знаете об этом, компилятор создаст для вас по умолчанию, и в этом случае пользователи смогут получить новый экземпляр через.

S scopy = S::getInstance(); 

4.Почему не мы реализовали две последние функции?

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

Обратите внимание, что одноэлемент часто рассматривается как anti-pattern. Что-то, что вы не хотите использовать без очень. И также разумно понимать проблемы с потоками, которые приходят с ним ... И затем помимо этого существует статическое фиаско порядка инициализации, с которым вы сталкиваетесь с некоторыми способами его реализации. (Способ в вашем коде в порядке, но довольно легко ошибиться.)

+0

Привет, о вопросе в 4-м абзаце?Означает ли это, что он может быть создан только один раз или это означает, что он может быть создан много раз, но в то время может существовать только одна копия? – nitinsh99

+1

Он будет создан только один раз, когда вызывается 'getInstance'. Но вы можете получать ссылки на него несколько раз. –

+0

Последнее, зачем нам гарантированное уничтожение этого экземпляра (как указано в коде)? Разве это не единственное требование синглтона, так это то, что «у него должен быть только один экземпляр», то почему мы должны беспокоиться о его освобождении? – nitinsh99

1

1) Да. Эта функция позволяет вам фактически получить один единственный экземпляр S. Поэтому вы звоните S::getInstance(). Если это не статично, вы не сможете этого сделать.

2, 3 и 4) Обратите внимание, что конструкторы и operator= являются закрытыми. Это должно помешать кому-то сделать другой экземпляр S, тем самым аннулируем статус singleton.

Вместо того, чтобы создавать свой собственный S, вы должны использовать S::getInstance(), чтобы получить один экземпляр.

1
  1. Да, он должен быть статическим, потому что ему не нужен указатель на экземпляр. Сделать его нестационарным было бы непродуктивным.

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

  3. Оператор присваивания operator=(S const&) используется, когда вы назначили новое значение этому экземпляру. Это не имеет смысла для singleton, поэтому объявляется закрытым и остается без реализации. Никто не может его использовать.

  4. Нет, конструктор копирования и оператор присваивания должны быть частными и без реализации. Это идиома C++, которая означает: Этот класс нельзя скопировать и не присвоить.

Смежные вопросы