Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Паттерн стратегия - скрыть одну из реализаций 
:(
    Опции темы
Tiarwe
Дата 17.9.2014, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 24.8.2011

Репутация: нет
Всего: нет



Добрый день!

Есть такой вот интерфейс:
Код

//DecoderInterface.h
class DecoderInterface
{
public:
    virtual void Decode() = 0;
};


От него наследуются реализации:
Код

//DecoderA.h
class DecoderA final : public DecoderInterface
{
public:
    virtual void Decode() override {};
};

//DecoderB.h
class DecoderB final : public DecoderInterface
{
public:
    virtual void Decode() override {}
};


Идея следующая: DecoderA был создан изначально программистом и его реализация скрыта от глаз (.h недоступен), DecoderB - добавлен в дальнейшем в процессе работы (.h доступен).

Этим всем делом заведует некий Decoder:
Код

//Decoder.h
class Decoder
{
public:
    template<typename T>
    void Initialize()
    {
        T* lT = new T();
        decoder = lT;
    }

private:
    DecoderInterface* decoder;
};


Соответственно, используется это дело так:
Код

// Main.cpp
int main()
{
    Decoder lDecoder1;
    lDecoder1.Initialize<DecoderA>();

    Decoder lDecoder2;
    lDecoder2.Initialize<DecoderB>();

    return 0;
}


Теперь мне нужно скрыть реализацию DecoderA с глаз:
Код

// Decoder.h
class DecoderA;

class Decoder
{
public:
    template<typename T>
    void Initialize()
    {
        T* lT = new T();
        decoder = lT;
    }

private:
    DecoderInterface* decoder;
};


Соответственно, при компиляции сыпятся ошибки, что для DecoderA не найден конструктор. Делаем специализацию, которую помещаем в .cpp (откуда будет виден DecoderA.h и виден конструктор этого класса):

Код

// Decoder.cpp
template<>
void Decoder::Initialize<DecoderA>()
{
    DecoderA* lDecoder = new DecoderA();
    decoder = lDecoder;
}


Снова ошибки при компиляции. Изменяем код следующим образом:
Код

// Decoder.h
class DecoderA;

class Decoder
{
public:
    template<typename T>
    void Initialize();

private:
    DecoderInterface* decoder;
};

// Decoder.cpp
template<>
void Decoder::Initialize<DecoderA>()
{
    DecoderA* lDecoder = new DecoderA();
    decoder = lDecoder;
}

// Main.cpp
int main()
{
    Decoder lDecoder1;
    lDecoder1.Initialize<DecoderA>();

    return 0;
}


Теперь реализация DecoderA работает, но инициализировать Decoder другими реализациями интерфейса нельзя, т.к. функции Initialize() определена лишь для спецификации DecoderA... Как, а главное можно-ли, заставить шаблон работать со всеми реализациями интерфейса, включая те, что скрыты от глаз разработчика (например DecoderA)?

Это сообщение отредактировал(а) Tiarwe - 17.9.2014, 23:40
PM MAIL   Вверх
Guinness
Дата 18.9.2014, 07:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: нет
Всего: 10



Цитата(Tiarwe @  18.9.2014,  00:39 Найти цитируемый пост)
 DecoderA был создан изначально программистом и его реализация скрыта от глаз (.h недоступен)

Я себе тяжело эту ситуацию представляю. Зачем и главное как потом с этим классом работать? Обычно интерфейс доступен, и он описывается в .h, а реализация прячется в .cpp. Допустим программист написал какую-то библиотеку, собрал её в виде lib или so. Реализация скрыта, но интейрфейс он в любом случае предоставляет с помощью файлов .h. Короче, я похоже не особо понял, что хочет ТС.
И ещё вопрос, а не проще сделать шаблонным весь класс, а не только функцию Initialize()?
PM MAIL   Вверх
baldina
Дата 18.9.2014, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



явно инстанцируйте шаблон в .cpp
http://ideone.com/3edSvg

PM MAIL   Вверх
Tiarwe
Дата 18.9.2014, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 24.8.2011

Репутация: нет
Всего: нет



Цитата(Guinness @ 18.9.2014,  07:00)
Цитата(Tiarwe @  18.9.2014,  00:39 Найти цитируемый пост)
 DecoderA был создан изначально программистом и его реализация скрыта от глаз (.h недоступен)

Я себе тяжело эту ситуацию представляю. Зачем и главное как потом с этим классом работать? Обычно интерфейс доступен, и он описывается в .h, а реализация прячется в .cpp. Допустим программист написал какую-то библиотеку, собрал её в виде lib или so. Реализация скрыта, но интейрфейс он в любом случае предоставляет с помощью файлов .h. Короче, я похоже не особо понял, что хочет ТС.
И ещё вопрос, а не проще сделать шаблонным весь класс, а не только функцию Initialize()?

Объясняю) Есть интерфейс для, например, рендера графики. Его реализации используют всякие OpenGL и DirectX функции. Если их засунуть в сорцы, затем собрать статическую библиотеку, то в дальнейшем, когда создаём какой-то новый проект и хотим рисовать графику, нет нужны таскать с собой хедеры DX, OpenGL и писать по 20 раз к ним пути. Достаточно просто прилинковать библиотеку и выбрать реализацию. Сейчас всё так и работает, но нет возможности указывать с какой именно реализацией мы хотим работать - она выбирается через перечисление, передаваемое в Initialize(). А если мне хочется использовать какую-то ещё новую реализацию, то приходится перегружать эту функцию и передавать в неё указатель.

Добавлено через 13 минут и 35 секунд
Цитата(baldina @ 18.9.2014,  10:48)
явно инстанцируйте шаблон в .cpp
http://ideone.com/3edSvg

Думал, не подходит. Допустим, у нас есть класс A, в котором есть Decoder. Его реализация может выбираться в зависимости от платформы.
PM MAIL   Вверх
math64
Дата 19.9.2014, 08:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Тогда нужно писать плагин. реализация класса в плагине, интерфейс в заголовке, используемом в основной программе и плагине.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0465 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.