Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.02.2021, 17:03   #1
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию Архитектурная идиома, в которой задействован так называемый заместитель (ргоху).

Здравствуйте! Вопрос из книги Брюса Эккеля, некоторые детали задания мне не ясны, хотелось бы их прояснить.

Цитата:
В этом упражнении используется архитектурная идиома, в которой задействован так называемый заместитель (ргоху). Начните с создания базового класса Subject и определите три функции: f(), g() и h(). Создайте производные от Subject классы Рrоху, а также классы Implementationl и Imp1ementa1ion2. Класс Ргоху содержит указатель на Subject, а все функции класса Ргоху должны перенаправлять свои вызовы через указатель на Subject. Конструктор Ргоху получает указатель на Subject, который запоминается в переменной класса. Создайте в функции main() два объекта Ргоху, использующие две разные реализации. Измените класс Ргоху так, чтобы он позволял динамически и переключаться с одной реализации на другую.
Я последний пункт понять не могу, как нужно изменить класс Proxy, может быть сделать его наследником Imlementation1 и Implementation2?

Код, на данный момент.
https://rextester.com/BTXPS4354


Код:
void checkImplementation()
{
cout << "Inplementation1, Implementation2 (1|2): ";
int ans;
cin >> ans;
if (ans == 1)
s = new Implementation1();
else if (ans == 2)
s = new Implementation2();
else
cerr << "Unknown type:\n";
}


Других вариантов не могу найти))
Если передать в заместитель указатель, то как-то я могу узнать и могу ли вообще это сделать, что он принадлежит Implementation1 или Implementation2 не могу сообразить, они же являются частью Subject.

Идея проста, как молоток, проверить, если это Implementation1, то создать с помощью new указатель на Implementation1, если это Implementation2 создать указатель на Implementation2, иначе присвоить значению поля класса Proxy значение Subject.

Но как проверить?... Вот в чём вопрос.

Надеюсь, что мои пояснения более или менее ясны!
apofioz вне форума Ответить с цитированием
Старый 15.02.2021, 18:30   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
Но как проверить?
Например параметром конструктора.

Ref:
https://en.wikipedia.org/wiki/Proxy_pattern#C++
waleri вне форума Ответить с цитированием
Старый 15.02.2021, 21:13   #3
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Например параметром конструктора.
И как это сделать, если я из main() передаю в функцию указатель на Implementation1 или Implementation2? Что с чем должно сравниваться? Или вместо указателя передавать некую константу, например, enum Impl{...}?
apofioz вне форума Ответить с цитированием
Старый 15.02.2021, 23:30   #4
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Код:
Implementation1* im1 = dynamic_cast<Implementation1*>(ss);
Implementation2* im2 = dynamic_cast<Implementation2*>(ss);
	if (im1)
		s = im1;
	else if (im2)
		s = im2;
	else
		s = ss;
Как вам такой вариант, имеет он право на существование?
apofioz вне форума Ответить с цитированием
Старый 16.02.2021, 07:20   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
имеет он право на существование
Имеет, но только зачем?
По логике Implementation1 и Implementation2 наследую один общий интерфейс, так что достаточно хранить указатель на него.
Если Implementation1 и Implementation2 - это разные интерфейсы, то это уже не прокси.
waleri вне форума Ответить с цитированием
Старый 16.02.2021, 13:53   #6
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
так что достаточно хранить указатель на него.
Я храню указатель на Subject, но как тогда динамически и переключаться с одной реализации на другую. Я об этом спрашивал, иначе у меня ничего путного не выходило. Здесь я в конструкторе автоматом, видимо, в этом и есть динамическое переключение, переключаю без особых заморочек...

Код:
Proxy(Subject* ss) :s(new Subject())
	{
		Implementation1* im1 = dynamic_cast<Implementation1*>(ss);
		Implementation2* im2 = dynamic_cast<Implementation2*>(ss);
		if (im1)
			s = im1;
		else if (im2)
			s = im2;
		else
			s = ss;

		cout << "CONSTRUCTOR PROXY(SUBJECT*)\t" << typeid(*this).name() << endl;
	}
Если есть более разумная реализация, то покажите, я учту на будущее.
apofioz вне форума Ответить с цитированием
Старый 16.02.2021, 14:18   #7
FrosyaZZ
Форумчанин
 
Регистрация: 16.11.2020
Сообщений: 243
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
Я храню указатель на Subject, но как тогда динамически и переключаться с одной реализации на другую.
В зависимости от каких-то условий поменять указатель.

Цитата:
Сообщение от apofioz Посмотреть сообщение
Здесь я в конструкторе автоматом, видимо, в этом и есть динамическое переключение, переключаю без особых заморочек...
Нет. Это не автоматом, тем более кастить вообще не надо.

Код:
struct Imp {
  virtual Func() = 0;
  virtual ~Imp() = default;
}

class Foo {
  Imp* imp{ nullptr };
...
}

void Foo::SuperFunc() {
  delete imp;
  if (pogoda.horosha()) {
    imp = new Imp1();
  else
    imp = new Imp2();

  imp->Func();
  ...
}
FrosyaZZ вне форума Ответить с цитированием
Старый 16.02.2021, 15:44   #8
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от FrosyaZZ Посмотреть сообщение
В зависимости от каких-то условий поменять указатель.
Ну, а чем не условие попытка узнать класс инициализируется Implementation1 или Implementation2?! Я не знаю, что имел автор книги, под задачей:
Цитата:
Сообщение от apofioz Посмотреть сообщение
Измените класс Ргоху так, чтобы он позволял динамически и переключаться с одной реализации на другую.
Я её понял так. То, что преобразование лишний раз применять не нужно - я читал, что это плохой стиль программирования - я понял, но бывают ситуации, когда можно и применить). Вот я и применил...
apofioz вне форума Ответить с цитированием
Старый 16.02.2021, 15:47   #9
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от FrosyaZZ Посмотреть сообщение
if (pogoda.horosha())
Это любое условие может быть, хоть:
Код:
if (a < b)
s = new Imp1;
else 
s = new Imp2;
apofioz вне форума Ответить с цитированием
Старый 16.02.2021, 15:54   #10
FrosyaZZ
Форумчанин
 
Регистрация: 16.11.2020
Сообщений: 243
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
Я её понял так.
Еще раз прочитайте и ответьте, как созданный вами объект будет динамически переключаться между реализациями? Разве вы сами не видите, что фактически сменить реализацию можно только пересозданием вашего объекта?
Смысл в таком объекте? Гораздо выгодней в таком случает сделать шаблонный класс и статически получить реализацию.

Цитата:
Сообщение от apofioz Посмотреть сообщение
Это любое условие может быть, хоть:
Да.
FrosyaZZ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Pascal Матрицы - элемент bij которой равен сумме элементов данной матрицы расположенных в области, определяемой индексами i,j так, как показано на рисунке users1 Помощь студентам 0 12.01.2017 06:04
Модифицировать программу так, чтобы она осуществляла поиск подматрицы n,в которой сумма элементов главной диагонали наибольшая АсяЯ Паскаль, Turbo Pascal, PascalABC.NET 0 05.11.2016 16:57
архитектурная компьютерная программа для создания дизайна igori.alekseev Свободное общение 2 16.01.2009 16:37