Форум программистов, компьютерный форум CyberForum.ru

Реализация Singleton - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 46, средняя оценка - 4.98
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
25.03.2012, 12:02     Реализация Singleton #1
Приветствую.

Пытался реализовать паттерн проектирования Singleton для лога след. образом:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Logger
{
    public:
        void log (const std::string& logMessage) const;
        static Logger& getInstance ();
 
    protected:
        static Logger loggerInstance;
        Logger ();
        ~Logger ();
};
 
void Logger::log (const std::string& logMessage) const
{
    std::cerr <<  logMessage.c_str () << std::endl;
}
 
Logger& Logger::getInstance ()
{
    return loggerInstance;
}
На этапе линковки проект падает:

error LNK2001: unresolved external symbol "protected: static class Logger Logger::loggerInstance" (?loggerInstance@Logger@@1V1@A)
Что не так?

Что делать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.03.2012, 12:02     Реализация Singleton
Посмотрите здесь:

C++ Реализация
Своя реализация new C++
C++ реализация цикла for
Singleton и DLL C++
Насчёт шаблонного паттерна SingleTon C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.03.2012, 12:08     Реализация Singleton #2
YourLastSong, нельзя объявлять поле loggerInstance в классе
поскольку на момент объявления класс еще не полностью объявлен
можно объявить только указатель
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
25.03.2012, 12:13  [ТС]     Реализация Singleton #3
Спасибо за совет!

Переписал вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Logger
{
    public:
        void log (const std::string& logMessage) const;
        static Logger* getInstance ();
 
    protected:
        static Logger *loggerInstance;
        Logger ();
        ~Logger ();
};
 
void Logger::log (const std::string& logMessage) const
{
    std::cerr <<  logMessage.c_str () << std::endl;
}
 
Logger* Logger::getInstance ()
{
    return loggerInstance;
}
 
Logger* Logger::loggerInstance = 0;
Деструктор, наверное, зря тут.

Может, стоит что-то ещё добавить?
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.03.2012, 12:17     Реализация Singleton #4
Цитата Сообщение от YourLastSong Посмотреть сообщение
Может, стоит что-то ещё добавить?
стоит
C++
1
2
3
4
5
6
Logger* Logger::getInstance ()
{
    if (!loggerInstance)
        loggerInstance = new Logger();
    return loggerInstance;
}
ну и конструктор по умолчанию с пустой реализацией
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
25.03.2012, 12:55  [ТС]     Реализация Singleton #5
А каким образом Вы бы реализовали наследование от базового класса Singleton, чтобы, например, иметь возможность сделать на основе данного класса Logger и, допустим, Settings?

Сделали бы класс Singleton абстрактным?

Можно пример, пожалуйста?
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.03.2012, 12:58     Реализация Singleton #6
почитай
Design Patterns: Elements of Reusable Object-Oriented Software
Автор: Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес
в издании 2001 года страница 134
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
25.03.2012, 13:28  [ТС]     Реализация Singleton #7
У меня сейчас возможности скачать, к сожалению, нет, пишу не с компьютера.

Можно попросить привести пример, если не сложно?

Добавлено через 26 минут
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
template <class T>
class Singleton
{
    public:
        virtual ~Singleton () {};
        static T* getInstance ()
        {
            if (!singletonInstance)
            {
                singletonInstance = new T ();
            }
            return singletonInstance;
        }
 
    protected:
        Singleton () {};
        static T* singletonInstance;
};
 
class Logger : public Singleton <Logger>
{
    private:
        Logger ();
 
    protected:
        friend class Singleton <Logger>;
 
    public:
        void log (const std::string& logMessage) const
        {
            std::cerr <<  logMessage.c_str () << std::endl;
 
            const std::string logFile = "log.txt";
            std::ofstream f (logFile, std::ios::app);
            f << logMessage << std::endl;
        }
};
К сожалению, на этапе линковки ругается при попытке использовать данный класс:

C++
1
Logger::getInstance ()->log ("abc");
error LNK2019: unresolved external symbol "private: __thiscall Logger::Logger(void)" (??0Logger@@AAE@XZ) referenced in function "public: static class Logger * __cdecl Singleton<class Logger>::getInstance(void)" (?getInstance@?$Singleton@VLogger@@@@SAPAVLogger@@XZ)
error LNK2001: unresolved external symbol "protected: static class Logger * Singleton<class Logger>::singletonInstance" (?singletonInstance@?$Singleton@VLogger@@@@1PAVLogger@@A)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.03.2012, 13:36     Реализация Singleton
Еще ссылки по теме:

C++ Singleton и MVC
C++ Объясните человеческим языком мне чайнику что такое singleton, статический класс. Зачем они нужны. Что рекомендуете прочитать мне для начала
Паттерн Singleton C++

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

Или воспользуйтесь поиском по форуму:
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
25.03.2012, 13:36     Реализация Singleton #8
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
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <cstdlib>
#include <fstream>
 
template <typename T>
class Singleton
{
public:
    virtual ~Singleton () {};
    static T* getInstance ()
    {
        if (!singletonInstance)
        {
            singletonInstance = new T ();
        }
        return singletonInstance;
    }
    
protected:
    Singleton () {};
    static T* singletonInstance;
};
 
template <typename T>
T* Singleton<T>::singletonInstance;
 
class Logger : public Singleton <Logger>
{
private:
    Logger() : Singleton<Logger>() {}
    
protected:
    friend class Singleton<Logger>;
    
public:
    void log(const std::string& logMessage) const
    {
        std::cerr <<  logMessage << std::endl;
        
        const std::string logFile = "log.txt";
        std::ofstream f(logFile.c_str(), std::ios::app);
        f << logMessage << std::endl;
    }
};
 
int main()
{
    Logger::getInstance()->log("abc");
    return EXIT_SUCCESS;
}
статическую переменную надо объявить после вне класса
Yandex
Объявления
25.03.2012, 13:36     Реализация Singleton
Ответ Создать тему
Опции темы

Текущее время: 03:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru