8

I'm very confused about this topic, basically I've this code:

template <typename T>
class SListArray
{
public:
    class const_iterator
    {
    public:
        const_iterator(size_t i_currentNode = -1)
            :m_position(i_currentNode)
        {
        }

        T const& operator*() const
        {
            return m_data[m_position].element;
        }

        // ...

    protected:
        size_t m_position;
    };

    explicit SListArray();

    // ...

private:
    std::vector<Node<T>> m_data;

    // ...
};

This code give me a compiler error, so, I would to know if is possible to give the Inner Class the acces to the members of the Outer Class.

Thanks.

bkaid
  • 51,465
  • 22
  • 112
  • 128
enigma
  • 456
  • 3
  • 8
  • Possible duplicate of [Can inner classes access private variables?](http://stackoverflow.com/questions/486099/can-inner-classes-access-private-variables) – Jason C Oct 31 '16 at 23:18

5 Answers5

10

Nested classes already have access to the containing class's members, assuming they have a pointer/reference to the containing class upon which to operate. Your iterator will need to store a reference to the outer class in order to be able to access the container as you appear to want.

Also note that protected data is usually a code smell and should typically be avoided. Prefer private data and a protected interface if appropriate.

EDIT: Unless this is strictly an exercise to learn how to program a container, just use one of the C++ standard containers such as vector which are well developed, debugged, and optimized.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • Yes, as I say to Nawaz, it's an exercise. Regard the protected data, it's so because I've an iterator class that inherits from const_iterator. – enigma Apr 20 '11 at 15:12
  • @enigma Are you sure that relationship represents substitution? It seems that in the long term inheriting your iterator from const_iterator may cause more problems than it solves in the short term. – Mark B Apr 20 '11 at 15:24
  • The non-const iterator can (or even should) derive from the const_iterator. Usually that way it's much easier to compare non-const and const iterators, assign a non-const iterator to a const-iterator, and so on. And it's a proper substitution: everywhere where a const_iterator can be used, a non-const iterator can also be used. – Sjoerd Apr 21 '11 at 21:33
  • I wish you'd spelled out how to get hold of the containing class. In the iterator constructor `this` refers to the iterator, not the containing class. And I can not add parameters to the constructor because then range-based iteration doesn't work. I think. – Victor Eijkhout May 22 '23 at 14:21
2

Yes, use a friend declaration.

private:
  std::vector<Node<T> > m_data;
  friend class const_iterator;

Update: Oh, and your access to m_data is wrong. The inner class cannot access the members of the outer class without a pointer to an instance of the outer class. So you have to adjust your const_iterator class to store a pointer/reference to the outer class, and use this pointer/reference in the operator*().

Sjoerd
  • 6,837
  • 31
  • 44
2

As Sjoerd already answered, you can give the access by using friend keyword. However, if you are looking for Java-style inner classes, there is no such thing in C++.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88
0

Although making const_iterator a friend of SListArray would solve your problem, but I'm wondering why don't you use std::vector . Why yet another new generic class?

If you're looking for a new name, then you can typedef as:

typedef std::vector<Node<int>>                 NodeList;
typedef std::vector<Node<int>>::iterator       NodeIterator;
typedef std::vector<Node<int>>::const_iterator NodeConstIterator;
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Your observation is correct. But I'm just implementing a Singly Linked List in different forms, for exercise. – enigma Apr 20 '11 at 15:10
0

Pass a reference:

class const_iterator {
public:
   const_iterator(ListArray<T> &arr) : arr(arr) { }
private:
   ListArray<T> &arr;
};

And then you need the friend stuff too.

tp1
  • 288
  • 1
  • 3