Доступ к подклассу C ++ - PullRequest
       7

Доступ к подклассу C ++

0 голосов
/ 10 сентября 2011

У меня есть основной класс, который наследуется многочисленными подклассами.Унаследованный основной класс должен быть как минимум защищен по наследству, чтобы не производные классы могли использовать или изменять его через подклассы.

Существует ли способ, позволяющий различным подклассам изменять унаследованные переменные основного класса друг друга, но без разрешения публичного доступа к основному классу?А без использования ключевого слова friend это приведет к сложному коду.

В полном контексте:

У меня есть класс узлов, который добавляет / удаляет узлы относительно него.Существует класс списка (и подклассы), который полагается на класс узла, что означает, что узел не может быть общедоступным в случае, если он также нарушает список классов.Узел также должен быть доступен для списка вспомогательных классов.

Чтобы это произошло, я реализовал узел под защитой внутри другого класса, узла доступа.Все классы, которым требуются права на узел, наследуют узел доступа как защищенный (поэтому класс узла доступа не является общедоступным).Это означает, что помощник и класс / подклассы списка получают доступ к узлу.

Проблема в том, что для TemplateList, чтобы копировать CharList (подкласс TemplateList) через доступ только для чтения, ему нужен доступ к узлам.CharList (чтобы избежать использования итератора CharList) - проблема в том, что узлы защищены (для предотвращения внешнего вмешательства, не связанного с узлами доступа), и реализация открытого метода, который предоставляет доступ к узлам, побеждает точку.

Мне нужно боковое наследование, поэтому все подклассы типа accessnode могут обращаться к узлам друг друга без публичного предоставления доступа.

Вкратце:

(Защищено) Узел внутри AccessNode.
TemplateList: Защищенный AccessNode.
CharList: Защищенный AccessNode.
Для TemplateList необходим доступ к CharList's AccessNode.
AccessNode / Node не может быть открытым.

Ответы [ 3 ]

2 голосов
/ 10 сентября 2011

Отказ от ответственности : Это совершенно не связано с этим конкретным вопросом, но больше с общей проблемой, которая привела вас к этому и другим сегодняшним вопросам.

Я думаю, что вы лаете не на то дерево здесь. У меня возникает ощущение, что вы предоставляете доступ к внутренним узлам вашего списка, а затем ожидаете, что сам тип узла защищает список от небрежных изменений (то есть тех, которые могут нарушить инварианты списка). При этом вы решаете сложное решение гораздо более простой проблемы: не позволяйте пользователям получать доступ к узлу в первую очередь.

Все станет намного проще, если вы посмотрите на подход, предоставленный STL, в отношении контейнеров и в частности списков. Список реализован в терминах некоторых неизвестных недоступных узлов. Спецификаторы доступа к операциям этих узлов вообще не имеют значения, поскольку пользователи не могут получить доступ к самому объекту, поэтому они могут быть публичными. Пользователи получают доступ к содержимому списка через другой прокси (iterator, const_iterator типы), который предоставляет только те операции, которые не могут испортить состояние списка.

1 голос
/ 10 сентября 2011

Я не совсем уверен, что понимаю, что вы подразумеваете под «подклассами [чтобы] изменять наследуемые переменные основного класса друг друга».

Если вы хотите разрешить доступ к переменной члена базового класса производным классамтолько тогда сделайте переменную-член protected.И / или добавьте функцию доступа protected.

Если вы хотите, чтобы различные экземпляры производных классов изменяли общие данные, хранящиеся в базовом классе, тогда вы можете добавить член static protectedПеременная к базовому классу.Все экземпляры будут использовать одну и ту же переменную-член.

Это поможет, если вы проясните проблему.

1 голос
/ 10 сентября 2011

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

РЕДАКТИРОВАТЬ :конкретный пример:

class Base
{
protected:
    struct State
    {
        int     m1;
        char    m2;

        State(): m1(), m2() {}
    };

    State   state_;

    static State& state( Base& o) { return o.state_; }
};

class Derived
    : public Base
{
public:
    void foo( Base& other )
    {
        Base::State&    baseState   = state( other );
        // Blah blah.
    }
};

int main()
{
    Derived o;
    // Blah blah.
}

Приветствия и hth.,

...