访问从成员函数返回的私有嵌套类

时间:2015-10-18 11:43:48

标签: c++

请帮助我理解为什么类成员函数可以返回私有嵌套类对象,以及为什么可以在该私有嵌套类上调用成员函数,例如:

class Y
{
    class X
    {
    public:
        void f() { cout << "Hello World" << endl; }
    };

public:
    X g() { return X(); }
};

void h()
{
    Y::X x;     // Error, as expected: class Y::X is private.
    x.f();      // Error.

    Y y;        // OK.
    y.g().f();  // OK. But why???
}

我使用GCC和Visual C ++进行了测试,最后一行在两者上进行了编译。我似乎无法在C ++标准中找到任何可以使其有效的内容。任何想法为何有效?

修改

另一个观察结果:

void i()
{
    Y y;

    Y::X x2 = y.g(); // Error: class Y::X is private
    x2.f();          // Error

    auto x3 = y.g(); // OK
    x3.f();          // OK
}

3 个答案:

答案 0 :(得分:5)

创建嵌套类private并不意味着外部作用域永远不能使用该类的实例。访问说明符会影响名称,而您的main函数永远不会尝试命名 Y::X 1 唯一的地方{ {1}}的名称在Y::X范围内,当然可以访问自己的Y成员。该函数返回privateY::X的实例并不是特别相关。

  

main班级成员可以是

     
      
  • [C++14: 11/1]:;也就是说,名称只能由声明它的类的成员和朋友使用
  •   
  • private;也就是说,它的名称只能由声明它的类的成员和朋友,从该类派生的类以及他们的朋友使用(见11.4)。
  •   
  • protected;也就是说,它的名称可以在没有访问限制的任何地方使用。
  •   

不可否认,该标准没有任何文本可以明确地让您失望,并指出对这些实体本身的访问不受这些关键字的控制,但这绝对是意图,并且最终,就法律术语而言。< / p>

1 它的名称为public,但该名称为Y::X::f

答案 1 :(得分:2)

  

为什么类成员函数可以返回私有嵌套类对象

嵌套类也是类成员,成员函数对私有成员具有访问权限。

  

以及为什么可以在该私有嵌套类

上调用成员函数

您在此处未使用私有嵌套类名,即Y::XY::X::f()是一个公共函数,因此可以直接调用它。

答案 2 :(得分:1)

在这里,您可以找到您要查找的示例。 f1是公开的,f2是私有的,会触发您所期望的错误:

#include <iostream>

class Y
{
    class X
    {
        public:
            void f1() { std::cout << "Hello World" << std::endl; }
        private:
            void f2() { std::cout << "Hello World" << std::endl; }
    };

    public:
        X g() { return X(); }
};

int main()
{
    // Y::X x;     // Error, as expected: class Y::X is private.
    // x.f();      // Error.

    Y y;         // OK.
    y.g().f1();  // OK. Because f1 is public.
    y.g().f2();  // Error. Because f2 is private.

    return 0;
}