Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.85.72] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
class T1{
private: C1 *pC1; C2 *pC2; }; class T2{ private C3 *pC3; }; Есть объекты T1 m1; T2 m2; Как из объекта m2 получить доступ к полю pC2 объекта m1? 1. При этом любой другой класс не должен иметь доступа к полю pC2! 2. При этом класс C2 должен иметь доступ только к pC2, поле pC1 должно оставаться для него недоступным. Хочу сделать что-то типа друга класса. Возожно ли это? Но вариант class T1{ private: friend T2; C1 *pC1; C2 *pC2; }; не проходит, ибо не выполняется условие 2. Как выполнить поставленную задачу? |
Сообщ.
#2
,
|
|
|
class T0 { protected: C1 *pC1; }; class T1: private T0 { private: friend class T2; C2 *pC2; }; |
Сообщ.
#3
,
|
|
|
Не понимаю, что это даёт?
pC1 станет protected для T1, а поскольку класс T2 станет другом для Т1, то и к рС1 он тоже будет иметь доступ. Или я не прав? Прошу приводить код с коммантариями Добавлено в : Да нет, не склероз. Просто раздел "Билдер" многие КЛАССНЫЕ программеры из раздела "Visual C" порсто не посещают. Вот потому я спрашиваю здесь |
Сообщ.
#4
,
|
|
|
Да такой пример действительно работать не будет. Забыл я его проверить.
Придётся так: class T0 { private: friend class T1; class C1 *pC1; }; class T1: public T0 { private: friend class T2; class C2 *pC2; }; Коментировать тут нечего доступ к pC1 имеет только T1, а разрешение на доступ к pC2 для T2 на pC1 не распространяется. |
Сообщ.
#5
,
|
|
|
Да это решение... намученное правда...
в этом случае действительно комменитировать нечего, поскольку код правилен и ясен. Спасибо. А ещё идеи есть? Например без использования дополнительного класса? З.Ы. 2Lucifer, видишь? Здесь есть более находчивые люди. |
Сообщ.
#6
,
|
|
|
class T1 { private: friend class FARSH; class C2 *pC2; class C1 *pC1; }; class FARSH { private: friend class T2; static C2 * GetpC2(T1& t1) { return t1.pC2; } }; class T2 { T1 t; public: T2() { C2 *pC2=FARSH::GetpC2(t); } }; class T2 { public: T2(class T1& t) { class C2 *pC2=GetpC2(t); } class C2 * GetpC2(T1& t1); }; class T1 { private: friend C2* T2::GetpC2(T1&); class C2 *pC2; class C1 *pC1; }; C2 * T2::GetpC2(T1& t1) { return t1.pC2; // Но тут при желании можно обратиться к pC1! } |
Сообщ.
#7
,
|
|
|
2Flip - извращенец (в хорошем смысле)
|
Сообщ.
#8
,
|
|
|
Можно конечно придумать ещё несколько извратов на данную тему, по разному наследовать промежуточный класс в том числе и от T2 есть варианты, отработать использование protected, скрыть дополнительные функции с помощью define или template. Но сделать, как мне кажется, это красиво ну никак не выйдет.
|
Сообщ.
#9
,
|
|
|
M Тopic moved here from Visual C++ / MFC / WTL / WinAPI |
Сообщ.
#10
,
|
|
|
Цитата Budda, 18.02.04, 11:26 Нужно чё-нить простое, но крутое! |
Сообщ.
#11
,
|
|
|
Можно замутить еще такой вариант. Предполагаем, что регулированием доступа занимается класс C1:
class C1 { public: C1() {;} private: // Объявляем класс, предоставляющий доступ class BaseAccessor { public: BaseAccessor(C1* parent) : m_Parent(parent) {;} int GetC1() {return m_Parent->m_C1;} int GetC2() {return m_Parent->m_C2;} private: C1* m_Parent; }; // Объявлеяем общий шаблон. Он будет использован для "остальных" классов template<class T> class Accessor_t { Accessor_t(C1* parent) {;}; }; // Объявляем специализацию, которая открывает доступ конкретному классу template<> class Accessor_t<C2*> : public BaseAccessor { public: Accessor_t(C1* parent) : BaseAccessor(parent) {;} }; friend class C1::BaseAccessor; int m_C1; int m_C2; public: // Метод, возвращающий объект, через который будем получать доступ. template<class T> Accessor_t<T*> GetAccess(T* obj) { return Accessor_t<T*>(this); } }; class C2 { public: void Foo(C1* ptr); }; void C2::Foo(C1* ptr) { ptr->GetAccess(this).GetC1(); ptr->GetAccess(this).GetC2(); } class C3 { public: void Foo(C1* ptr); }; void C3::Foo(C1* ptr) { //ptr->GetAccess(this).GetC1(); //ptr->GetAccess(this).GetC2(); } Под студией, если раскомментарить последние две строчки - будет ошибка компиляции. |
Сообщ.
#12
,
|
|
|
Этот вариант легко модифицируется к варианту со статическими методами. А используя приватное наследование и using можно легко регулировать доступ для разных классов.
|
Сообщ.
#13
,
|
|
|
сильно намучено, помимо прочего, не могу понять назначение вот этого:
// Объявлеяем общий шаблон. Он будет использован для "остальных" классов template<class T> class Accessor_t { Accessor_t(C1* parent) {;}; }; // Объявляем специализацию, которая открывает доступ конкретному классу template<> class Accessor_t<C2*> : public BaseAccessor { public: Accessor_t(C1* parent) : BaseAccessor(parent) {;} }; |
Сообщ.
#14
,
|
|
|
В С++ существует такая вещь - специализация шаблонов. Используется тогда, когда для конкретного типа шаблон должен вести себя особым образом. В приведенном примере у нас получается следующее. Общая специализация:
Цитата Budda, 18.02.04, 16:46 template<class T> class Accessor_t { Accessor_t(C1* parent) {;}; }; Не содержит никаких методов доступа. Таким образом, когда мы будем инстанцировать этот шаблон - ни к какому методу мы обратиться не сможем (по причине их отсутствия). Теперь делаем взмах руками над клавиатурой и... Цитата Budda, 18.02.04, 16:46 template<> class Accessor_t<C2*> : public BaseAccessor { public: Accessor_t(C1* parent) : BaseAccessor(parent) {;} }; Получаем, что если мы будем инстанцировать шаблон Accessor_t для типа C2*, то получим доступ к методам, объявленным в классе BaseAccessors. Т. е. объекты Accessor_t<C2*> c2_accessor(); и Accessor_t<C3*> c3_accessor(); будут вести себя по-разному и будут содержать разные методы. Теперь мы еще немножко напрягаем компилятор, и делаем так, что он сам выбирает для нас нужную специализацию: // Метод, возвращающий объект, через который будем получать доступ. template<class T> Accessor_t<T*> GetAccess(T* obj) { return Accessor_t<T*>(this); } используя факт того, что шаблонные методы могут инстанцироваться неявно. В итоге мы можем использовать все это описанным мною способом: void C2::Foo(C1* ptr) { ptr->GetAccess(this).GetC1(); ptr->GetAccess(this).GetC2(); } При этом доступом управляет сам класс C1, и на этапе компиляции мы получаем жесткий контроль - классы, которым "не положено" доступа не получат. |
Сообщ.
#15
,
|
|
|
Эх нужно тестить, абстрактно догнать не могу....
|