Синглтон в CPP - PullRequest
       21

Синглтон в CPP

2 голосов
/ 02 ноября 2011

Ниже приведен код для одноэлементного класса


class single{
private:
    int i;
    single(int x): i(x){ 

    }
public:
    static single& getInstance(){
        static single s(10);
        return s;
    }

    void incPrint(){
        ++i;
        cout i  " ";
    }
};

Теперь один и тот же код дает два разных результата для 2 разных кодов


single d1 = single::getInstance();
    d1.incPrint();
    d1.incPrint();

    single d2 = single::getInstance();
    d2.incPrint();
    d2.incPrint();

Этот код выдает:

11 12 11 12

Принимая во внимание, что этот код


    single & d1 = single::getInstance();
    d1.incPrint();
    d1.incPrint();

    single & d2 = single::getInstance();
    d2.incPrint();
    d2.incPrint();

дает результат

11 12 13 14

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

Спасибо

Ответы [ 3 ]

9 голосов
/ 02 ноября 2011

T x = foo() делает копию.

Или ведет себя «как будто» он сделал копию.

Хотя T& x = foo(), когда foo возвращает ссылку T&, только делает ссылку.


Сделать конструктор копирования и оператор присваивания частным. Это помешает людям делать копии всех. Сделав оператор присваивания копии личным, вы не сможете выполнить самокопирование.

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

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

Приветствия и hth.,

2 голосов
/ 02 ноября 2011

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

Этот код:

single d1 = single::getInstance();

означает:

Создать новую переменную типа single и скопировать возвращенную ссылку для ее инициализации.Поэтому каждый раз, когда вы делаете это, вы создаете новую переменную вместо использования переменной singleton.

Этот код:

single & d1 = single::getInstance();

означает:

Создать новая ссылка на ту же переменную, что и возвращаемая ссылка.Поэтому каждый раз, когда вы делаете это, вы получаете ссылку на переменную singleton, как вам нужно.

Чтобы вы (и другие) не допустили этой ошибки, вы должны сделать свой конструктор приватным.

2 голосов
/ 02 ноября 2011

Удалить конструктор копирования (сделать его закрытым).Это помешает людям делать копии.

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

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

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