0
class X
{
    int Xi;

    class Y
    {
        int Yi;

        void func()
        {
            X x;
            x.Xi = 5;
        }
    };

    void func()
    {
        Y y;
        y.Yi = 5;
    //  ^^^^ 'X::Y::Yi': cannot access private member declared in class 'X::Y'
    }
};

I was learning about the Memento pattern and in the book I read, it was stated that one of the ways of achieving the pattern is by writing the Memento class inside the Originator class so that only the Originator can have access to the private members of the Memento class. When I tried to apply this method I got an error telling me that the private member is inaccessible. I know that I can use the keyword friend and that will give me access to the private members. Also I know that I can access the outer class's private members from the inner class. But why can't the inner class access the private members of the inner class?

I can do this in java for example:

public class X {

    int Xi;

    public class Y
    {
        private int Yi;

        public void func()
        {
            X x = new X();
            x.Xi = 5;
        }
    }

    public void func()
    {
        Y y = new Y();
        y.Yi = 5;
    }
}

Why is it not doable in C++?

StackExchange123
  • 1,871
  • 9
  • 24

1 Answers1

1

Despite the title of your question, what you are trying to do on the line y.Yi = 5; is access a private member of the inner class from the body of the outer class. This you cannot do, because the Yi member is private - so it can only be accessed from inside its class.

On the other hand, the linex.Xi = 5; does indeed access a private member of the outer class from the inner class; this, you are allowed to do, because your inner Y class is part of the outer X class.

One way to get round this is to declare the X::func() function a friend of class Y; however, you will then need to provide a 'prototype' of that function before you make that declaration, and you would thus need to make the actual definition of the function outside the class body (it must come after the class Y declaration, as it uses an object of that class):

class X {
private: // Even without this line, members are private by default!
    int Xi;
    void func(); // Just a declaration (prototype) - wwwe still need the definition
    class Y {
    private:
        int Yi;
        void func() {
            X x;
            x.Xi = 5;
        }
        friend void X::func();
    };
};

void X::func() { // This is the actual definition of the function.
    Y y;
    y.Yi = 5;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • What if we make the variable as "friend" in case of trying to access the private members? – Rohan Bari Apr 20 '20 at 13:07
  • I've updated the quesion. I can do it in java but not in c++. What is the reason for not making this possible in C++? – StackExchange123 Apr 20 '20 at 13:17
  • 1
    @LinuXMan Yes - you could allow the access to happen by declaring `class Y` as a `friend` of `class X` - just put the line `friend class X;` somewhere inside the definition of `class Y`. – Adrian Mole Apr 20 '20 at 13:20
  • @StackExchange123 C++ and Java are different languages and have different rules. I don't really 'do' Java, so I can't speak for why the code you have added works. – Adrian Mole Apr 20 '20 at 13:21
  • @LinuXMan Or you could just make the X::func()` function a friend - see edit. – Adrian Mole Apr 20 '20 at 13:30
  • @StackExchange123 You can try the code I have given: maybe C++ is inherently less **friendly** than Java is? ‎ – Adrian Mole Apr 20 '20 at 13:33
  • @AdrianMole yeah I've just seen your edited code. That used as a friend function to access the subclass member. I've just answered another way to do so by just making the class members public. – Rohan Bari Apr 20 '20 at 13:36