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

Bar*_*ett 5 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???
}
Run Code Online (Sandbox Code Playgroud)

我使用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
}
Run Code Online (Sandbox Code Playgroud)

Lig*_*ica 5

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

[C++14: 11/1]: 一个班级的成员可以

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

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

1它确实有名字Y::X::f,但名字是public.

  • 有趣的。我没有意识到 `auto` 允许声明否则是不可能的。我一直认为 `auto` 主要是一个方便的功能。 (2认同)