crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> подклассы Singlton
call_me_Frank
  опции профиля:
сообщение 25.2.2015, 13:50
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


Привет!

не могу найти примера того, как нужно использовать подклассы Singlton'а Мейерса.
суть задачи проста: нужен абстрактный класс логгера, и несколько его реализаций - для файловой системы, для БД, для консоли и т.д. Конечно, сам Логгер на всю программу должен быть в ед. экземпляре.

Вот чего-то я запутался в этих трех соснах. :blink: Help me, please!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 9)
Iron Bug
  опции профиля:
сообщение 25.2.2015, 15:18
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


как-то непонятно, чего ты хочешь. singleton всегда имеет один экземпляр. что значит "несколько реализаций"?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
call_me_Frank
  опции профиля:
сообщение 25.2.2015, 15:44
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


я планирую сделать так:

наследовать от QObject (юзаю Кьют) некий базовый подкласс (от которого наследовать остальные классы), в котором объявлен логгер, и потом где-то как-то выбирать конкретный логгер, используемый приложением:

// BASE.H

class BASE : public QObject

    LOGGER * logger;
    ...
};

// BASE.CPP

BASE::BASE(QObject) {

    switch(log_type){

        case 0: logger = FILE_LOGGER::get_instance();
        case 1: logger = DB_LOGGER::get_instance();
        case 2: logger = CONSOLE_LOGGER::get_instance();
    }

    ...

    logger->log("BINGO!");
};


FILE_LOGGER, DB_LOGGER & CONSOLE_LOGGER - соответственно, являются наследниками класса LOGGER с переопределенными методами log(const QString &msg);

появилось мнение, что с Мейерсом такой вариант не прокатит, и нужно использовать реализацию синглтона с указателем? или я вообще не в ту степь повернул?)

Сообщение отредактировал call_me_Frank - 25.2.2015, 15:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 25.2.2015, 15:55
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


ты пытаешься применить паттерн фабрики к синглтону. про паттерны можешь почитать здесь: http://www.wiki.crossplatform.ru/index.php/Design_Patterns
посмотри "Фабричный метод". там примерно то, что ты пытаешься изобразить, насколько я понимаю.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
call_me_Frank
  опции профиля:
сообщение 25.2.2015, 16:17
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


именно!

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

Собственно, я не могу понять: все классы (LOGGER & FILE_LOGGER, DB_LOGGER, ...) должны быть реализованы как Singleton, или не все? если FILE_LOGGER, наследует LOGGER и в классе BASE я использую интерфейс класса LOGGER, значит надо прописать в нем виртуальную ф-ию log(QString), для того, что бы переопределить её в FILE_LOGGER. Но если класс LOGGER является Singlton'ом, то значит ф-ия log() должна быть static...вот какие противоречия роятся у меня в голове :blink:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
call_me_Frank
  опции профиля:
сообщение 25.2.2015, 17:26
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


решил! 8)

// .H

#ifndef CLASS1_H
#define CLASS1_H

#include <iostream>

enum LOG_TYPE {LOG_C1 = 0, LOG_C2 = 1};

class class1;

class c1Dest
{
    class1 * _inst;
public:
    ~c1Dest();
    void init(class1 * p);
};

class class1
{
    static class1 * __inst;
    static c1Dest dest;

    static LOG_TYPE type;
protected:
    class1(){}
    class1(const class1&);
    class1& operator=(class1&);
    ~class1(){}

    friend class c1Dest;
public:
        static class1& instance();
    virtual void echo();
};

class class2 : public class1
{
public:
    void echo();
};

#endif // CLASS1_H


// .CPP

#include "class1.h"

LOG_TYPE class1::type = LOG_C1;

class1 * class1::__inst = 0;
c1Dest class1::dest;

c1Dest::~c1Dest(){
    delete _inst;
}

void c1Dest::init(class1 *p){
    _inst = p;
}

class1& class1::instance(){
    if (!__inst){
        switch (type){
            case LOG_C1: __inst = new class1; break;
            case LOG_C2: __inst = new class2; break;
        }
        dest.init(__inst);
    }
    return *__inst;
}

void class1::echo(){
    std::cout << "class1::echo() " << this << std::endl;
}

void class2::echo(){
    std::cout << "class2::echo() " << this << std::endl;
}


пригодна такая реализация? сделал, порадовался...теперь засомневался <_<

и появился вопрос: как развязать классы по отдельным h-файлам? получается зацикленное включение хедеров

Сообщение отредактировал call_me_Frank - 25.2.2015, 17:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
call_me_Frank
  опции профиля:
сообщение 25.2.2015, 18:41
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вот еще один вариант реализации с помощью шаблонов:

template<class T>
class SingleTonePattern {

public:
    static T& getInstance() {
        static T instance;
        return instance;
    }

    virtual void echo() = 0;
};

class CustomSingleTone : public SingleTonePattern<CustomSingleTone>
{
    friend class SingleTonePattern<CustomSingleTone>;
private:
    CustomSingleTone() {}

public:
    virtual void echo() {
       qDebug() << "ECHO!!";
    }
};


и вызов:

    CustomSingleTone &st = SingleTonePattern<CustomSingleTone>::getInstance();
    st.echo();


что скажете?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 25.2.2015, 19:02
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


насчёт решения с классами - какое-то оно странное. честно говоря, непонятно, как это будет использоваться. подумай ещё. это полезно. и обязательно попробуй использовать свои классы, без этого ты не поймёшь потенциальных минусов своего решения.

Цитата(call_me_Frank @ 25.2.2015, 19:26) *
и появился вопрос: как развязать классы по отдельным h-файлам? получается зацикленное включение хедеров

это стандартное решение в С/C++. каждый хэдер всегда заключён в блок препроцессорных определений:
#ifndef SOME_HEADER_NAME
#define SOME_HEADER_NAME
....
<код>
....
#endif

и ещё: лучше не использовать имена переменных, начинающиеся с двух подчёркиваний ( __ ) - часто это зарезервированные имена служебных переменных и функций и можно случайно напороться на конфликт с определениями в стандартных библиотеках.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 25.2.2015, 19:11
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


не совсем понятно, зачем этот огород?
qDebug() все эти вещи решает вполне прозрачно, или любой другой подобный объект.
Вывод всегда можно направить в нужное место.

Цитата(call_me_Frank @ 25.2.2015, 17:26) *
и появился вопрос: как развязать классы по отдельным h-файлам? получается зацикленное включение хедеров


обычно так решают:
#ifndef SOMEHEADER_H
#define SOMEHEADER_H

#include <otherheader.h>

class SomeClass
{
};

#endif //SOMEHEADER_H


Сообщение отредактировал wiz29 - 25.2.2015, 19:14
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 25.2.2015, 19:11
Сообщение #10


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(wiz29 @ 25.2.2015, 21:06) *
не совсем понятно, зачем этот огород?

это просто упражнение на технику программирования. весьма полезное, кстати.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 5.12.2024, 5:23