请帮助我理解为什么类成员函数可以返回私有嵌套类对象,以及为什么可以在该私有嵌套类上调用成员函数,例如:
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
}
答案 0 :(得分:5)
创建嵌套类private
并不意味着外部作用域永远不能使用该类的实例。访问说明符会影响名称,而您的main
函数永远不会尝试命名 Y::X
。 1 唯一的地方{ {1}}的名称在Y::X
范围内,当然可以访问自己的Y
成员。该函数返回private
到Y::X
的实例并不是特别相关。
main
班级成员可以是
[C++14: 11/1]:
;也就是说,其名称只能由声明它的类的成员和朋友使用。private
;也就是说,它的名称只能由声明它的类的成员和朋友,从该类派生的类以及他们的朋友使用(见11.4)。protected
;也就是说,它的名称可以在没有访问限制的任何地方使用。
不可否认,该标准没有任何文本可以明确地让您失望,并指出对这些实体本身的访问不受这些关键字的控制,但这绝对是意图,并且最终,就法律术语而言。< / p>
1 它的名称为public
,但该名称为Y::X::f
。
答案 1 :(得分:2)
为什么类成员函数可以返回私有嵌套类对象
嵌套类也是类成员,成员函数对私有成员具有访问权限。
以及为什么可以在该私有嵌套类
上调用成员函数
您在此处未使用私有嵌套类名,即Y::X
。 Y::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;
}