С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880

Паттерн Singleton

14.09.2014, 22:41. Показов 3988. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Мне вот дали такой код как паттерн Singleton:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "stdafx.h"
 
template <class T>
class SingletonS
{
    static int m_nCount;
    static T *m_pWork;
public:
 
    SingletonS()
    {
        if (++m_nCount == 1)
        {
            m_pWork = new T;
            cout << " Constructor Singleton typeS: " << this << endl;
        }
    }
 
    ~SingletonS()
    {
        if (--m_nCount == 0)
        {
            delete m_pWork;
            cout << " Destructor Singleton typeS: " << this << endl;
        }
    }
 
 
    T* operator ->()
    {
        return m_pWork;
    }
 
};
 
// объявляем static-переменные (шаблоны)
template <class T>
int SingletonS<T>::m_nCount;
 
template <class T>
T * SingletonS<T>::m_pWork;
Я почитал об паттерне Singleton в книге "Приемы ООП паттерны проектирования",
не все я там понял, но суть в том, что там "немного не так".
Собственно вопрос: Суть паттерна одиночки в выше указанном коде, сохраняется?
Или все таки есть какая та разница?

Добавлено через 47 минут
Вроде вопрос легкий)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.09.2014, 22:41
Ответы с готовыми решениями:

Паттерн Singleton
Здравствуйте. Например есть класический одиночка и загрузка музыки. Возможно ли сделать загрузку и вопроизведение музыки через класс...

Singleton. Одиночка. Паттерн
Как реализовать паттерн Singleton на C++? Делаю так: Заголовочный файл: class Play { private: Play(void); ~Play(void);

Что значит Singleton& operator = ( Singleton& )?
// Singleton.h class Singleton { private: static Singleton * p_instance; // Конструкторы и оператор присваивания...

22
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
14.09.2014, 22:48
Если это и singleton, то какой-то очень корявый:

1.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include "SingletonS.h"
 
using namespace std;
 
struct foo
{
    int Value;
    foo() : Value(0) {}
};
 
typedef SingletonS<foo> single_foo;
 
void put_value(int Value)
{
    single_foo SingleFoo;
    SingleFoo->Value = Value;
}
 
void show_value()
{
    single_foo SingleFoo;
    cout << SingleFoo->Value << endl;
}
 
int main()
{
    put_value(123);
    show_value();
    return 0;
}
> Constructor Singleton typeS: 0xffb03edf
> Destructor Singleton typeS: 0xffb03edf
> Constructor Singleton typeS: 0xffb03edf
> 0
> Destructor Singleton typeS: 0xffb03edf
Нормальный синглтон выдал бы 123 вместо 0.

2.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include "SingletonS.h"
 
using namespace std;
 
struct foo
{
    int Value;
    foo() : Value(0) {}
};
 
typedef SingletonS<foo> single_foo;
 
single_foo get_single()
{
    single_foo SingleFoo;
    return SingleFoo;
}
 
int main()
{
    single_foo SingleFoo = get_single();
    cout << SingleFoo->Value << endl;
    return 0;
}
> Constructor Singleton typeS: 0xff85ca8f
> Destructor Singleton typeS: 0xff85ca8f
> -1785358955
Где же ты, нормальная копия объекта ?

3.
Класс не потокобезопасен (для синглтона это бывает важно).

4.
Про мелочи типа "stdafx.h" и использования cout вообще молчу.

Резюме: на помоечку.

Добавлено через 19 секунд
Цитата Сообщение от andreyananas Посмотреть сообщение
Вроде вопрос легкий)
Вроде воскресенье
0
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
14.09.2014, 22:56
Здравствуйте, в данном случае используется шаблонный класс, позволяющий сгенерировать синглтон для переданного в качестве параметра шаблона класса. При этом сам по себе класс SingletonS не является синглтоном, т.к. публичный конструктор позволяет создавать любое число копий этого класса. Он обеспечивает внутри себя создание только одной копии класса T - при условии (++m_nCount == 1), и удалении этой копии при (--m_nCount == 0). Это можно назвать вариацией на тему синглтона который поддерживает некоторый инвариант поведения( не более одной копии T созданной при помощи класса SingletonS<T> в программе), сходный с описываемым паттерном синглтон, но не более. T может иметь публичный конструктор - и создавай сколько влезет. SingletonS<T> можно создать, удалить, потом снова создать - будет создана новая копия T. Кроме того конструктор копирования и оператор присваивания не прикрыты в этой реализации - что приведет к интересным последствиям.
0
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880
15.09.2014, 00:24  [ТС]
Цитата Сообщение от Melg Посмотреть сообщение
Здравствуйте, в данном случае используется шаблонный класс, позволяющий сгенерировать синглтон для переданного в качестве параметра шаблона класса...
Это я понял. Но в результате мы получим тот же эффект как у сингилтона или нет? Если нет, тогда в чем разница?
0
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
15.09.2014, 00:51

Не по теме:

Эффект Синглтона. Неплохое название для триллера или мальчуковой группы.


Цитата Сообщение от andreyananas Посмотреть сообщение
Но в результате мы получим тот же эффект как у сингилтона или нет?
Нет. Пользователь вашего этого того может создать несколько инстансов, что как бэ ломает саму суть паттерна.
Ещё, как заметил товарищ Убежденный, ваше оно это не потокобезопасно.
Как исправить:
1. Сделать конструктор private или protected, если захотите наследоваться;
2. Для потокобезопастности ввести проверки (double-checked locking) или исхитриться со статичностью (lazy initialization).
О, а после всего этого вашего того... забыть про этот паттерн. Это же глобальные переменные только в ОО стиле.
Админь.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
15.09.2014, 01:04
Подправить для начала:
C++
1
2
3
4
SingletonS():m_nCount(0),m_pWork(0)
{
 
}
C++
1
2
3
4
5
6
7
8
9
T* operator ->()
{
   if(!m_pWork)
   {
      m_pWork = new T;
      ++m_nCount;
   }
   return m_pWork;
}
0
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880
15.09.2014, 01:24  [ТС]
Цитата Сообщение от Andrej Посмотреть сообщение
вашего этого того
Цитата Сообщение от Andrej Посмотреть сообщение
ваше оно это
Цитата Сообщение от Andrej Посмотреть сообщение
этого вашего того
Это такой юмор? Или я забыл русский?

Добавлено через 2 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Код C++

C++
1
2
3
SingletonS():m_nCount(0),m_pWork(0)
{
}
Не катит... Тогда при каждый раз счетчик будет обносятся.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
15.09.2014, 01:25
Цитата Сообщение от andreyananas Посмотреть сообщение
Не катит... Тогда при каждый раз счетчик будет обносятся.
Так уже сказали что пользователь не должен иметь возможности создавать экземпляр класса.

C++
1
T* operator ->()
Тут я поспешил должен быть статический метод.
C++
1
static T* instance()
0
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880
15.09.2014, 01:28  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Про мелочи типа "stdafx.h" и использования cout вообще молчу.
А вы не молчите, я только учусь)
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
15.09.2014, 01:32
Цитата Сообщение от Убежденный Посмотреть сообщение
Класс не потокобезопасен (для синглтона это бывает важно).
Цитата Сообщение от Andrej Посмотреть сообщение
2. Для потокобезопастности ввести проверки (double-checked locking) или исхитриться со статичностью (lazy initialization).
А вот тут и мне интересно, ибо нигде не видел примера реализации или описание сего.
0
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880
15.09.2014, 01:55  [ТС]
Цитата Сообщение от Andrej Посмотреть сообщение
2. Для потокобезопастности ввести проверки (double-checked locking) или исхитриться со статичностью (lazy initialization).
по подробней плс.

Добавлено через 9 минут
Вообщем, напишите плс нормальный Singleton, если не сложно.
Или киньте ссылку на него.
0
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
15.09.2014, 02:31
Вот наклепал на скорую руку Lazy Initialized Singleton (все обязательно с бошой буквы).
Как известно (ой тут местные гуру могут избить меня тапками) статические переменные находятся в data segment,
но не инициализированны. Инициализируются они при первом вызове функции/метода, куда они впихнуты.
При потере области видимости (выходе из функции) они не теряются как переменные на стэке, а продолжают жить пока программа не закончится.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
 
class LazySingleton { // иначе называется Meyer's singleton
private:
        LazySingleton() { std::cout << "LazySingleton ctor." << '\n'; } // чтобы посмотреть сколько раз звался ктор
        ~LazySingleton() { std::cout << "LazySingleton dtor." << '\n'; }
public:
        static LazySingleton&
        getInstance()
        {
                static LazySingleton singleton; // здесь весь сахар и происходит, статичная переменная же!
                return singleton;
        }
 
        void
        method()
        {
                std::cout << "called method" << '\n'; // какой-то метод
        }
};
 
void // какая-то функция
function()
{
        std::cout << "from function ";
        LazySingleton::getInstance().method(); // а инстанс уже создан, только позвать метод
}
 
int
main(int argc, char** argv)
{
        LazySingleton::getInstance().method(); // здесь создается инстанс и зовется его метод
        function();
        system("pause"); // проверял под вянды на msvc2013
    return 0;
}
Double-checked locking - довольно часто используется в многопоточных приложениях (или мне так не везёт).
Суть в чём: стандартная проверка на существование в синглтоне показывает, что инстанса нет, значит, можно создать. Ан нет! Если дело вертится в нескольких потоках, все несколько иначе. После проверки на существование инстанса, другой поток может также выполнить эту проверку. Оба увидят, инстансов нет. И вот два инстанса. Паттерн сломан.
C++
1
2
3
if (!instance) { // 1й поток сделал проверку и заморозился. 2й сделал проверку и прошел её, создав инстанс
    return instance; // 1й разморозился и создал инстанс
}
Решается так:
C++
1
2
3
4
5
6
7
8
if (!instance) {
     lock_mutex; // лочьте ваш любимый вид мутекса
     if (!instance) {
          pInstance = instance
     }
     unlock_mutex;
     return pInstance;
}
Сейчас есть доступ только к виндовой машине, а в вяндовую многопоточность не умею. Так что, дальше гуглите сами.
Ну и ленивый синглтон напоточте, если интересно.

Добавлено через 2 минуты
Цитата Сообщение от andreyananas Посмотреть сообщение
Это такой юмор? Или я забыл русский?
О, петросяню понемногу. Звиняйте, если что.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.09.2014, 08:33
Andrej, кстати с С++11 необходимость в Double-checked locking отпала (в Meyer's singleton) из-за гарантий стандарта насчет инициализации статических переменных.
0
Zn
3 / 3 / 0
Регистрация: 26.06.2014
Сообщений: 37
15.09.2014, 11:21
Цитата Сообщение от andreyananas Посмотреть сообщение
Или киньте ссылку на него.
Не надейся, что здешние еврейские жиды тебе скинут хороший синглтон. ))) Я сейчас вспомню с какого проекта выдергивал его и тебе здесь отпишу. ))
0
 Аватар для andreyananas
27 / 27 / 11
Регистрация: 15.10.2013
Сообщений: 880
15.09.2014, 12:40  [ТС]
Вообщем пошла инфаааааааа которую я совсем уже не понимаю(
Цитата Сообщение от Zn Посмотреть сообщение
Я сейчас вспомню с какого проекта выдергивал его и тебе здесь отпишу.
спс, буду ждать)
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
15.09.2014, 13:04
Да но:
C++
1
2
3
4
5
        void
        method()
        {
                std::cout << "called method" << '\n'; // какой-то метод
        }
То же должен быть с "залочиванием"
1
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
15.09.2014, 13:48
Цитата Сообщение от Avazart Посмотреть сообщение
То же должен быть с "залочиванием"
О, а ведь точно!
0
Zn
3 / 3 / 0
Регистрация: 26.06.2014
Сообщений: 37
15.09.2014, 14:51
Цитата Сообщение от andreyananas Посмотреть сообщение
спс, буду ждать)
Вспомнил ))

Вот отсюда
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
15.09.2014, 15:58
Цитата Сообщение от Andrej Посмотреть сообщение
Double-checked locking - довольно часто используется в многопоточных приложениях (или мне так не везёт).
Double-checked locking это анти-паттерн. Он не работает в общем случае из-за out of ordering execution. Плюс еще могут быть проблемы с атомарностью записи в pInstance ( например из-за невыровненности )
0
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
15.09.2014, 16:19
Цитата Сообщение от Voivoid Посмотреть сообщение
например из-за невыровненности
А можете дать ссылки на чтиво об этом? Интересно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.09.2014, 16:19
Помогаю со студенческими работами здесь

Singleton
Буду краток. Пропустил пару по Singleton( это только первое занятие было по паттернам). Дали лабу по singleton , а я ничего не пойму....

Singleton и DLL
DLL .h class EXPORT LOG { public: LOG() { x = this; } void test();

Реализация Singleton
Приветствую. Пытался реализовать паттерн проектирования Singleton для лога след. образом: class Logger { public: void...

Singleton и MVC
Здравствуйте уважаемые форумчане. Изучаю с++ и столкнулся с понятием паттернов и парадигмы MVC. Прочитав про паттерны и погуглив не...

Singleton vs static class
Зачем этот синглтон, если его можно представить как класс с статическими полями и методами. Какой случай я упускаю?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru