为什么在嵌套 class 时无法从内部 class 访问外部 class 的私有成员?

Why can't I access private members of the outer class from the inner class when nesting classes?

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'
    }
};

我正在学习 Memento 模式,在我读的书中,有人指出实现该模式的方法之一是在 [=15] 中编写 Memento class =] class 这样只有 Originator 可以访问 Memento class 的私有成员。当我尝试应用此方法时,我收到一条错误消息,告诉我无法访问私有成员。我知道我可以使用关键字 friend,这样我就可以访问私有成员。我还知道我可以从内部 class 访问外部 class 的私有成员。但是为什么内层class不能访问内层class的私有成员呢?

我可以在 java 中执行此操作,例如:

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;
    }
}

为什么在 C++ 中不可行?

不管你的问题的标题是什么,你试图在行 y.Yi = 5; 上做的是访问 inner[ 的私有成员=39=] class 从 外层 body class。你不能这样做,因为 Yi 成员是 private - 所以它只能从其 class.

内部访问

另一方面,行x.Xi = 5;确实访问了outer[=54=的私有成员] 来自 class;你可以这样做,因为你的内部 Y class 是外部 X class.

的一部分

解决这个问题的一种方法是将 X::func() 函数声明为 class Yfriend;但是,您需要在做出声明之前提供该函数的'prototype',因此您需要做出实际的定义 函数 之外 class body (它必须在 class Y 声明之后,因为它使用 object 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;
}
#include <iostream>

using namespace std;

class X
{
    public:
    int Xi;

    class Y
    {
        public:
        int Yi;

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

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

在此代码中,我刚刚将 class 成员设置为 public。