C++嵌套类的可访问性

28

给定以下代码不考虑两个类之间的友谊关系:

class OutSideClass
{
...
public:
    int i_pub;
protected:
    int i_pro;
private:
    int i_pri;

    class InSideClass
    {
        ...
        public:
            int j_pub;
        protected:
            int j_pro;
        private:
            int j_pri;
    };
};

问题1:OutSideClass只能访问InSideClass的公共成员,这是真的吗?

问题2:InSideClass可以访问OutSideClass的所有成员,这是真的吗?

如果我的理解有误,请纠正我。

4个回答

34

问题1> 是否真的只有OutSideClass可以访问InSideClass的公共成员?

是的。

问题2> 是否真的InSideClass可以访问OutSideClass的所有成员?

在C++03中不行,在C++11中可以。


标准文本非常清楚:

C++标准(2003年版)在$11.8/1 [class.access.nest]中说:

嵌套类的成员没有特殊访问权来访问封闭类的成员,也没有访问授予封闭类友元的类或函数;应遵守通常的访问规则(第11条款)。封闭类的成员没有特殊访问权来访问嵌套类的成员;应遵守通常的访问规则(第11条款)。

但是,标准引语有一个缺陷。它说嵌套类无法访问封闭类的私有成员。但是在C++11中已经纠正了这个问题:在C++11中,嵌套类确实可以访问封闭类的私有成员(尽管封闭类仍然无法访问嵌套类的私有成员)。

请参阅此缺陷报告:


根据您的回答,似乎我在最新的C++标准中的所有答案都是正确的? - q0987
@q0987。是的(在C++0x标准中)。 :-) - Nawaz

3
在C++03中,嵌套类没有访问其封闭类成员的特殊权限,但可以通过将嵌套类声明为友元来轻松解决此限制,正如@Nawaz指出的那样
class OutSideClass
{
...

    class InSideClass
    {
        ...
    };
    friend class InSideClass;
};

当我这样做时,似乎InSideClass无法通过名称引用OutSideClass的成员变量? - JoseOrtiz3
@OrangeSherbet 你能创建一个[mcve]来展示问题吗? - Praetorian
我现在明白你说的是C++03。同时我看到这个问题只涉及到访问权限。无论如何,我认为值得指出的是,一个嵌套的InnerClass只能通过引用&OuterClass的特定实例来访问OuterClass的非静态成员变量,以便像我这样的新手不会尝试打破C++的规则。 - JoseOrtiz3

1

C++中嵌套类的作用就是将内部类放置在外部类的命名空间中。要从OutSideClass的成员函数中实例化InSideClass的实例,只需执行以下操作:

InSideClass *instance = new InSideClass();

如果 InsideClass 是公共的,而我想从不是 OutSideClass 的成员函数中实例化 InSideClass,则应输入以下代码:

OutSideClass::InSideClass *instance = new OutSideClass::InSideClass();

InSideClass和OutSideClass在其他语言(如Java)中是完全独立的,没有任何关联。


正如在其他地方提到的那样,从C++11开始,这不是它们所做的全部。嵌套类也被隐式授予对封装类的友元访问。这已经在C++11中被规范化了,但我认为在此之前各种编译器都以非正式的方式完成了此操作。 - underscore_d

-2

嵌套类对封闭类没有特殊的访问权限。


哪一个是最新的?C++03还是C++0x? - q0987
2
@q0987:C++0x 是最新的版本。C++03 意味着在2003年标准化的 C++ 语言。因此,C++0x 大多数将类似于 C++11,在今年发布。 - Nawaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接