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

Access to private nested class returned from member function

本文关键字:嵌套 返回 成员 函数 访问      更新时间:2023-10-16

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

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
}

将嵌套类设为private并不意味着外部作用域永远不能使用该类的实例。 访问说明符会影响名称,并且 main 函数永远不会尝试命名Y::X1 Y::X唯一被命名的地方是在Y内,当然,它可以访问自己的private成员。该函数将Y::X实例返回给main并不是特别相关。

[C++14: 11/1]: 类的成员可以是

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

诚然,该标准没有任何文本可以明确地使您感到困惑,并指出对这些关键字的访问不受这些关键字的控制,但这绝对是意图,最终,就法律术语而言。

1 它确实命名Y::X::f,但这个名字是public

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

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

以及为什么可以在该私有嵌套类上调用成员函数

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

在这里你可以找到你正在寻找的例子。 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;
}