【问题标题】:Why can't I access private members of the outer class from the inner class when nesting classes?为什么嵌套类时不能从内部类访问外部类的私有成员?
【发布时间】:2020-08-02 23:37:12
【问题描述】:
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 模式,并且在我阅读的书中指出,实现该模式的方法之一是在 Originator 类中编写 Memento 类,这样只有 Originator可以访问Memento 类的私有成员。当我尝试应用此方法时,我收到一条错误消息,告诉我私有成员不可访问。我知道我可以使用关键字friend,这将使我能够访问私人成员。我也知道我可以从内部类访问外部类的私有成员。但是为什么内部类不能访问内部类的私有成员呢?

例如,我可以在 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++ 中不可行?

【问题讨论】:

    标签: c++ class private inner-classes access-specifier


    【解决方案1】:

    尽管你的问题是标题,但你在y.Yi = 5; 上尝试做的是从主体访问 inner 类的私有成员外部类。这是您无法做到的,因为Yi 成员是私有的 - 所以它只能从其类内部访问。

    另一方面,linex.Xi = 5; 确实从 inner 访问 outer 类的私有成员 类;这个,你可以这样做,因为你的内部 Y 类是外部 X 类的一部分。

    解决此问题的一种方法是将X::func() 函数声明为class Y朋友;但是,您需要在进行该声明之前提供该函数的“原型”,因此您需要对函数进行实际的定义 >在类主体之外(它必须在class Y 声明之后,因为它使用该类的对象):

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

    【讨论】:

    • 如果我们将变量设为“朋友”以防尝试访问私有成员怎么办?
    • 我已经更新了问题。我可以用 java 做,但不能用 c++ 做。在 C++ 中无法实现这一点的原因是什么?
    • @LinuXMan 是的 - 您可以通过将 class Y 声明为 friendclass X 来允许访问发生 - 只需将行 friend class X; 放在 class Y 的定义中的某处。
    • @StackExchange123 C++ 和 Java 是不同的语言,有不同的规则。我并没有真正“做”Java,所以我无法说明为什么您添加的代码有效。
    • @LinuXMan 或者您可以将 X::func()` 函数设为好友 - 请参阅编辑。
    【解决方案2】:
    #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;
        }
    };
    

    在这段代码中,我刚刚公开了类成员。

    【讨论】:

    • 当然,让会员 public 会起作用 - 但这可能会违背目的,因为它会被所有人和各种各样的人访问。
    猜你喜欢
    • 2017-01-25
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2021-01-05
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多