Почему вложенный класс не объявляется другом?

93
01 января 2022, 15:10

Внутреннему классу MyIterator нужно получить доступ к приватному полю RBTree<T,R> tree, лежащему во внешнем классе Map:

template<class T,class R>
class Map 
{
    friend class MyIterator;
public:
    Map();
    ~Map();
    R& operator[](T index)
    {
        return tree.searchOperator(index);
    }
class MyIterator : public iterator<bidirectional_iterator_tag, RBTNode<T, R>>
    {
        public:
        MyIterator(RBTNode<T, R> it)
        {
            second = it.Element.second;
            first = it.Element.first;
        }
        MyIterator()
        {
        }
        MyIterator& operator=(const MyIterator& it) 
        {
        }
        MyIterator& operator*()
        {
            //пустует. 
        }
        MyIterator(const MyIterator& source)
        {
            first = source.first;
            second = source.second;
        }
        MyIterator operator++(int) 
        {//Post ++
            RBTNode<T, R>* pt = tree.search(first);
            pt =tree.Inc(pt);
            //MyIterator tmp = *this;
            *this.first=pt.Element.first;
            *this.second = pt.Element->second;
            return *this;
        }
        MyIterator operator->()
        {
            //
            return (**this);
        }
    public:
        T first;
        R second;
    };
    MyIterator begin()
    {
        RBTNode<T, R> pt = tree.f_begin();
        MyIterator temp(pt);
        return temp;
    }
private:
     RBTree<T,R> tree;//хочу сделать доступным в MyIterator
    //RBTNode<T, R> tempnode;
};
template <class T,class R>
Map<T, R>::Map() {

}
template <class T, class R>
Map<T,R>::~Map()
{
}

Кого и как объявить другом,чтобы эта перегрузка имела доступ к экземпляру дерева?

        MyIterator operator++(int) 
        {//Post ++
            RBTNode<T, R>* pt = tree.search(first);//Ошибка tree идентификатор не найден
            pt =tree.Inc(pt);
            //MyIterator tmp = *this;
            *this.first=pt.Element.first;
            *this.second = pt.Element->second;
            return *this;
        }
Answer 1

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

Ваш класс (шаблон) Map::MyIterator - это совершенно независимый класс. Поле tree является членом класса Map и доступ к полю tree возможен только через конкретный экземпляр класса Map. У вас в методе Map::MyIterator::operator ++ нет никакого экземпляра класса Map. Поэтому и никакого tree нет тоже.

Если вы хотите, чтобы Map::MyIterator был привязан к конкретному экземпляру класса Map и брал оттуда член tree, то вам эту связь придется организовывать самостоятельно вручную. Тот факт, что Map::MyIterator объявлен внутри Map абсолютно никак вам в этом не помогает, кроме предоставления вышеупомянутого права доступа.

READ ALSO
Visual studio с++ бинарная совместимость

Visual studio с++ бинарная совместимость

У меня есть сторонняя dll, скомпилированная в vs2008Исходников ее нету

197
Поиск палиндрома максимальной длины

Поиск палиндрома максимальной длины

Создать файл из N целых чиселНайти отрезок массива максимальной длины, в котором первое число равно последнему, второе - предпоследнему...

183