Класс Singleton в C ++ - PullRequest
       39

Класс Singleton в C ++

3 голосов
/ 18 января 2012

Я использовал синглтон-вызов по примеру:

синглтон-класс

Но я получаю ошибку как "Неразрешенные внешние символы"

это код, который я опробовал:

#include<iostream>
using namespace std;

class singleton
{
    int value;
    static singleton *instance;
protected:
    singleton()
    {
        value=0;
    }
public:
    static void initialize()
    {
        if(instance==NULL)
            singleton();
        else
            cout<<"An instance of singleton already exist...";
    }
    static singleton& getInstance()
    { 
        return *instance; 
    }
    int getValue() 
    { 
        return value; 
    }

};

void main()
{
    singleton::initialize();
}

Небольшое объяснение классов Singleton было бы действительно здорово.Сценарий его используется.Преимущества и недостатки.Альтернативы синглтону.и т.д.

Ответы [ 3 ]

9 голосов
/ 18 января 2012

Для начала я думаю:

singleton();

должно быть:

instance = new singleton();

Как у вас есть, вы на самом деле не храните вновь созданный объект, поэтому instance будет всегда быть нулевым.

Это также хорошая форма для явной установки статики с помощью:

singleton *singleton::instance = 0;

(вне определения класса).

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

#include <iostream>

class singleton {
    protected:
        static singleton *instance;
        singleton() { }
    public:
        static singleton *getInstance() {
            if (instance == 0)
                instance = new singleton();
            return instance;
        }
};
singleton *singleton::instance = 0;

int main() {
    singleton *s1 = singleton::getInstance();
    singleton *s2 = singleton::getInstance();
    std::cout << s1 << '\n';
    std::cout << s2 << '\n';
    return 0;
}

Вы видите, что оба указателя совпадают с выводом:

0xbc0358
0xbc0358

Или эталонная версия, поскольку, похоже, вы на это нацелены:

#include <iostream>

class singleton {
    protected:
        static singleton *instance;
        singleton() { }
    public:
        static singleton& getInstance() {
            if (instance == 0)
                instance = new singleton();
            return *instance;
        }
};
singleton *singleton::instance = 0;

int main() {
    singleton &s1 = singleton::getInstance();
    singleton &s2 = singleton::getInstance();
    std::cout << &s1 << '\n';
    std::cout << &s2 << '\n';
    return 0;
}
5 голосов
/ 18 января 2012

В вашем файле определения вам нужно определение instance:

singleton* singleton::instance = NULL;

Вы должны отделить ваше определение от декларации, если вы хотите использовать синглтон в нескольких единицах перевода.

Кроме того, способ, которым это обычно делается, не имеет метода инициализации:

static singleton* getInstance()
{ 
    if(instance==NULL)
        instance = new singleton();
    return instance;
}

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

3 голосов
/ 18 января 2012

Вам необходимо определить статическую переменную-член instance. Где-нибудь в глобальной области видимости (например, между классом и функцией main) добавьте следующую строку:

singleton *singleton::instance = 0;  // use 'nullptr' if your compiler support it

Кроме того, вы можете поместить инициализацию экземпляра в getInstance:

static singleton& getInstance()
{
    if (instance == 0)
        instance = new singleton;
    return *instance;
}

и удалите функцию initialize.

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

...