защищенный Observer
От: xlend  
Дата: 30.05.07 15:37
Оценка:
Допустим, у нас есть 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 в этом случае? (А нельзя ли сделать по другому?)
Re: защищенный Observer
От: MasterZiv СССР  
Дата: 30.05.07 16:10
Оценка:
xlend пишет:

> Так вот в чем вопрос: насколько оправдано использование friend в этом

> случае? (А нельзя ли сделать по другому?)

Не уверен, что доконца все додумал, но кажется можно сделать
Observer приватным интерфейсом и выдавать его только Subject-у.
Конкретный Observer будет предоставлять этот интерфейс только
своим Subject-ам. Но при этом надо как-то скрыть получение
этого интерфейса от публики, там тоже либо Subject-а делать
другом, либо его конкретный метод, либо FactoryMethod, который
их двоих создает и увязывает.

Главное — зачем это все ? ничего страшного же не должно
происходить, если вызвать в произвольное время Update у
обзервера. Даже полезно может быть — типа пункт меню
Refresh view.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: защищенный Observer
От: xlend  
Дата: 30.05.07 16:59
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Главное — зачем это все ? ничего страшного же не должно

MZ>происходить, если вызвать в произвольное время Update у
MZ>обзервера. Даже полезно может быть — типа пункт меню
MZ>Refresh view.

Если честно, мне хотелось бы передавать в параметрах а что собственно изменилось. Это уже совсем не Model-View.
Тут 'Model', которая не хранит данные о себе а сразу перенаправляет их, по мере поступления.
ПОпоравьте меня, если это глупая затея
Re: защищенный Observer
От: Sm0ke Россия ksi
Дата: 31.05.07 10:47
Оценка:
Здравствуйте, xlend, Вы писали:

X>Допустим, у нас есть Observer из Гаммы, который выглядит вот так (упрощенно):


X>
X>class Subject;

X>class Subject
X>{
X>        Observer &e;

X>public:
X>        Subject(Observer &e): e(e) {}

X>        void Act()
X>        {
X>                e.Update();
X>        }
X>};

X>class Observer
X>{
X>public:
X>        void Update()
X>        {
X>                std::cout << "update\n";
X>        }
X>};
X>


X>Не нравится мне то, что пользователь может вызвать Update тогда, когда это не нужно. Поэтому решено было Update сделать приватным, а Observer — другом Subject. Чтобы закрыть остальные данные от Subject, создаем предка Observer, которому прописываем другом Subject и объявляем там абстрактный метод Update():


nested classes?

class Observer
{
private:
        void Update()
        {
                std::cout << "update\n";
        }

public:
        class Subject
        {
                Observer &e;
        public:
                Subject(Observer &e): e(e) {}

                void Act()
                {
                        e.Update();
                }
        };
};


Вложенный класс является другом внешнего.

void fn_test()
{
  Observer ob;
  Observer::Subject subj(ob);
  subj.Act();
}
Re[2]: защищенный Observer
От: Аноним  
Дата: 31.05.07 11:21
Оценка:
S>nested classes?

S>
S>class Observer
S>{
S>private:
S>        void Update()
S>        {
S>                std::cout << "update\n";
S>        }

S>public:
S>        class Subject
S>        {
S>                Observer &e;
S>        public:
S>                Subject(Observer &e): e(e) {}

S>                void Act()
S>                {
S>                        e.Update();
S>                }
S>        };
S>};
S>


S>Вложенный класс является другом внешнего.


S>
S>void fn_test()
S>{
S>  Observer ob;
S>  Observer::Subject subj(ob);
S>  subj.Act();
S>}
S>

ппц, BCB6 не поддерживает и это (Update is not accessible)...

это является стандартом? где можно прочитать про это?
Re: защищенный Observer
От: Seon  
Дата: 31.05.07 11:38
Оценка:
Здравствуйте, xlend, Вы писали:

X>
X>class Subject;

X>class SubjectEvent
X>{
X>public:
X>        virtual void Update() {}
X>friend class Subject;
X>};

X>class Subject
X>{
X>        SubjectEvents &e;

X>public:
X>        Subject(SubjectEvent &e): e(e) {}

X>        void Act()
X>        {
X>                e.Update();
X>        }
X>};

X>class Observer : public SubjectEvent
X>{
X>        void Update()
X>        {
X>                std::cout << "update\n";
X>        }
X>public:

X>};
X>


X>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)


Конкретно в этом случае friend вообще не нужен.
Re[2]: защищенный Observer
От: xlend  
Дата: 31.05.07 13:33
Оценка:
Здравствуйте, 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:

};
Re[2]: защищенный Observer
От: hVostt Россия http://hvostt.ru
Дата: 31.05.07 18:55
Оценка:
Здравствуйте, Sm0ke, Вы писали:

[skipped]

S>Вложенный класс является другом внешнего.


S>
S>void fn_test()
S>{
S>  Observer ob;
S>  Observer::Subject subj(ob);
S>  subj.Act();
S>}
S>


один фиг френдить надо, хоть вложенный, хоть внешний — побарабану
... << RSDN@Home 1.2.0 alpha rev. 677>>
специализация — удел насекомых... (с) Р. Хайнлайн
Re[3]: защищенный Observer
От: hVostt Россия http://hvostt.ru
Дата: 31.05.07 18:57
Оценка:
Здравствуйте, <Аноним>, Вы писали:


А>ппц, 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 {};
то то и не нравится мне: по-уродски выглядит _тройное_ по сути описание...
а вот студия почему то съедает приведенный выше код (без френд объявлений).
и после этого говорят, что студия очень близка к стандарту?!
Re: защищенный Observer
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 01.06.07 15:42
Оценка:
Здравствуйте, xlend, Вы писали:

X>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)


Можно — через делегирование ... передовать указатель на фуе-ию ... если осилишь будет намного удобнее чем через френда, получится типа аналога как на джабе через анонимные классы ...
Re[5]: защищенный Observer
От: hVostt Россия http://hvostt.ru
Дата: 01.06.07 18:57
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>>>ппц, BCB6 не поддерживает и это (Update is not accessible)...

А>>>это является стандартом? где можно прочитать про это?

А>тогда вначале предварительное объявление класса class myclass; friend myclass; class myclass {};

А>то то и не нравится мне: по-уродски выглядит _тройное_ по сути описание...

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

А>а вот студия почему то съедает приведенный выше код (без френд объявлений).

А>и после этого говорят, что студия очень близка к стандарту?!

у мелкософтов свой взгляд на стандарт, вообще они не привыкшие следовать общим стандартам, они привыкли рулить
... << RSDN@Home 1.2.0 alpha rev. 677>>
специализация — удел насекомых... (с) Р. Хайнлайн
Re[2]: защищенный Observer
От: xlend  
Дата: 01.06.07 21:26
Оценка:
X>>Так вот в чем вопрос: насколько оправдано использование friend в этом случае? (А нельзя ли сделать по другому?)

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


Если ты имеешь в виду указатель на функцию-член, то это удобно но мне кажется это немного некорректно, потому что с помощью таких указателей можно получать доступ к private и protected полям откуда бы то ни было
Re[4]: защищенный Observer
От: LelicDsp Россия  
Дата: 03.06.07 08:18
Оценка: 2 (1)
V>нехватает friend <вложенное имя класса>, стандарт подобные вольности не позволяет
У меня нет стандарта 2003 года, но видел утверждение, что в нем вложенный класс всегда является другом (в отличие от 1998). Вот ссылка http://www.mozilla.org/hacking/portable-cpp.html#inner_classes. VS2005 думает так же.
Re[5]: защищенный Observer
От: hVostt Россия http://hvostt.ru
Дата: 03.06.07 09:44
Оценка:
Здравствуйте, LelicDsp, Вы писали:

V>>нехватает friend <вложенное имя класса>, стандарт подобные вольности не позволяет

LD>У меня нет стандарта 2003 года, но видел утверждение, что в нем вложенный класс всегда является другом (в отличие от 1998). Вот ссылка http://www.mozilla.org/hacking/portable-cpp.html#inner_classes. VS2005 думает так же.

видимо на счет стандарта я ошибался, но для портабельности все-таки надо френдить, засунув в deprecated-секцию кода.
... << RSDN@Home 1.2.0 alpha rev. 677>>
специализация — удел насекомых... (с) Р. Хайнлайн
Re[3]: offtopic
От: Sm0ke Россия ksi
Дата: 06.06.07 08:29
Оценка:
Здравствуйте, xlend, Вы писали:

X>Если ты имеешь в виду указатель на функцию-член, то это удобно но мне кажется это немного некорректно, потому что с помощью таких указателей можно получать доступ к private и protected полям откуда бы то ни было


Нраится мне этот си++
"Вообще-то это нельзя, но если вы очень хотите, то можно."
Re: защищенный Observer
От: Аноним  
Дата: 08.06.07 07:44
Оценка:
Здравствуйте, xlend, Вы писали:

Раз уж зашла речь об обсерверах, очень рекомендую не изобретать велосипед, а использовать boost::signal.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.