Допустим, у нас есть Observer из Гаммы, который выглядит вот так (упрощенно):
class Subject;
class Subject
{
Observer &e;
public:
Subject(Observer &e): e(e) {}
void Act()
{
e.Update();
}
};
class Observer
{
public:
void Update()
{
std::cout << "update\n";
}
};
Не нравится мне то, что пользователь может вызвать Update тогда, когда это не нужно. Поэтому решено было Update сделать приватным, а Observer — другом Subject. Чтобы закрыть остальные данные от Subject, создаем предка Observer, которому прописываем другом Subject и объявляем там абстрактный метод Update():
class Subject;
class SubjectEvent
{
public:
virtual void Update() {}
friend class Subject;
};
class Subject
{
SubjectEvents &e;
public:
Subject(SubjectEvent &e): e(e) {}
void Act()
{
e.Update();
}
};
class Observer : public SubjectEvent
{
void Update()
{
std::cout << "update\n";
}
public:
};
Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)
xlend пишет:
> Так вот в чем вопрос: насколько оправдано использование friend в этом > случае? (А нельзя ли сделать по другому?)
Не уверен, что доконца все додумал, но кажется можно сделать
Observer приватным интерфейсом и выдавать его только Subject-у.
Конкретный Observer будет предоставлять этот интерфейс только
своим Subject-ам. Но при этом надо как-то скрыть получение
этого интерфейса от публики, там тоже либо Subject-а делать
другом, либо его конкретный метод, либо FactoryMethod, который
их двоих создает и увязывает.
Главное — зачем это все ? ничего страшного же не должно
происходить, если вызвать в произвольное время Update у
обзервера. Даже полезно может быть — типа пункт меню
Refresh view.
Здравствуйте, MasterZiv, Вы писали:
MZ>Главное — зачем это все ? ничего страшного же не должно MZ>происходить, если вызвать в произвольное время Update у MZ>обзервера. Даже полезно может быть — типа пункт меню MZ>Refresh view.
Если честно, мне хотелось бы передавать в параметрах а что собственно изменилось. Это уже совсем не Model-View.
Тут 'Model', которая не хранит данные о себе а сразу перенаправляет их, по мере поступления.
ПОпоравьте меня, если это глупая затея
X>Не нравится мне то, что пользователь может вызвать Update тогда, когда это не нужно. Поэтому решено было Update сделать приватным, а Observer — другом Subject. Чтобы закрыть остальные данные от Subject, создаем предка Observer, которому прописываем другом Subject и объявляем там абстрактный метод Update():
Здравствуйте, Seon, Вы писали:
X>>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?) S>Конкретно в этом случае friend вообще не нужен.
Сорри, описался, хотел написать это:
class Subject;
class SubjectEvent
{
virtual void Update() {}
friend class Subject;
};
class Subject
{
SubjectEvents &e;
public:
Subject(SubjectEvent &e): e(e) {}
void Act()
{
e.Update();
}
};
class Observer : public SubjectEvent
{
void Update()
{
std::cout << "update\n";
}
public:
};
А>ппц, BCB6 не поддерживает и это (Update is not accessible)...
А>это является стандартом? где можно прочитать про это?
нехватает friend <вложенное имя класса>, стандарт подобные вольности не позволяет
в гугле "область видимости вложенных классов"
... << RSDN@Home 1.2.0 alpha rev. 677>>
специализация — удел насекомых... (с) Р. Хайнлайн
Re[4]: защищенный Observer
От:
Аноним
Дата:
01.06.07 07:13
Оценка:
Здравствуйте, hVostt, Вы писали:
V>Здравствуйте, <Аноним>, Вы писали:
А>>ппц, BCB6 не поддерживает и это (Update is not accessible)...
А>>это является стандартом? где можно прочитать про это?
тогда вначале предварительное объявление класса class myclass; friend myclass; class myclass {};
то то и не нравится мне: по-уродски выглядит _тройное_ по сути описание...
а вот студия почему то съедает приведенный выше код (без френд объявлений). и после этого говорят, что студия очень близка к стандарту?!
Здравствуйте, xlend, Вы писали:
X>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)
Можно — через делегирование ... передовать указатель на фуе-ию ... если осилишь будет намного удобнее чем через френда, получится типа аналога как на джабе через анонимные классы ...
Здравствуйте, <Аноним>, Вы писали:
А>>>ппц, BCB6 не поддерживает и это (Update is not accessible)... А>>>это является стандартом? где можно прочитать про это?
А>тогда вначале предварительное объявление класса class myclass; friend myclass; class myclass {}; А>то то и не нравится мне: по-уродски выглядит _тройное_ по сути описание...
по-мойму вполне логично, вложенный класс — это просто ограничение видимости, а не автоматический френд. так-то вложенный класс или не вложенный, он является отдельной самостоятельной еденицей. поэтому если необходим доступ к защищенным членам, надо явно френдить, тогда понятен смысл класса еще с порога его описания
А>а вот студия почему то съедает приведенный выше код (без френд объявлений). А>и после этого говорят, что студия очень близка к стандарту?!
у мелкософтов свой взгляд на стандарт, вообще они не привыкшие следовать общим стандартам, они привыкли рулить
X>>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)
S>Можно — через делегирование ... передовать указатель на фуе-ию ... если осилишь будет намного удобнее чем через френда, получится типа аналога как на джабе через анонимные классы ...
Если ты имеешь в виду указатель на функцию-член, то это удобно но мне кажется это немного некорректно, потому что с помощью таких указателей можно получать доступ к private и protected полям откуда бы то ни было
V>нехватает friend <вложенное имя класса>, стандарт подобные вольности не позволяет
У меня нет стандарта 2003 года, но видел утверждение, что в нем вложенный класс всегда является другом (в отличие от 1998). Вот ссылка http://www.mozilla.org/hacking/portable-cpp.html#inner_classes. VS2005 думает так же.
Здравствуйте, LelicDsp, Вы писали:
V>>нехватает friend <вложенное имя класса>, стандарт подобные вольности не позволяет LD>У меня нет стандарта 2003 года, но видел утверждение, что в нем вложенный класс всегда является другом (в отличие от 1998). Вот ссылка http://www.mozilla.org/hacking/portable-cpp.html#inner_classes. VS2005 думает так же.
видимо на счет стандарта я ошибался, но для портабельности все-таки надо френдить, засунув в deprecated-секцию кода.
Здравствуйте, xlend, Вы писали:
X>Если ты имеешь в виду указатель на функцию-член, то это удобно но мне кажется это немного некорректно, потому что с помощью таких указателей можно получать доступ к private и protected полям откуда бы то ни было
Нраится мне этот си++
"Вообще-то это нельзя, но если вы очень хотите, то можно."
Re: защищенный Observer
От:
Аноним
Дата:
08.06.07 07:44
Оценка:
Здравствуйте, xlend, Вы писали:
Раз уж зашла речь об обсерверах, очень рекомендую не изобретать велосипед, а использовать boost::signal.