我正在阅读C ++ 11 Standard(N3092)。
11-4成员访问控制说
访问控制统一应用于所有名称,无论名称是从声明还是表达式中引用。 [注意:访问控制适用于由朋友声明((11.4)和using-声明(7.3.3)提名的名称。 —尾注]
11.4-9朋友说
由朋友声明指定的名称应在包含该朋友声明的类的范围内可访问。 朋友声明的含义与朋友声明出现在类成员规范的私有,受保护或公共(9.2)部分中一样。
由于我的英语水平差,这两个摘录似乎不一致。如第一节摘录所述,如果将访问控制应用于friend
,该怎么办?谁能给我一个具体的示例代码?
第一节摘录还提到了using
声明。可以通过下面的代码确认。因此,您可以说“访问控制肯定适用于使用声明”。但是我不知道如何编写代码来查看访问控制的friend
函数的行为。
#include <iostream>
using std::cout;
class B {
public:
void f() { cout << "B::f()\n"; }
void f(int) { cout << "B::f(int)\n"; }
};
class D : public B {
public:
using B::f; //`using` declaration in `public` context
void f() { cout << "D::f()\n"; }
};
class D2 : public B {
using B::f; //`using` declaration in `private` context
public:
void f() { cout << "D2::f()\n"; }
};
int main() {
D d;
d.f(); //=> "D::f()"
d.f(0); //=> "B::f(int)"
D2 d2;
d2.f(); //=> "D2::f()"
d2.f(0); //=> "error: ‘void B::f(int)’ is inaccessible within this context"
}
如上面的代码,如果我写
public:
friend void some_func() { }
,访问控制是否应用于名称some_func
?怎么样?
答案 0 :(得分:3)
这两个摘录似乎不一致
它们是一致的,但不一定如此。 [note: ]
块中的所有内容均为非标准文本。此处仅出于人类目的进行概述或提供澄清的示例,但并未用于定义语言的实际行为。因此,唯一重要的摘录是第二篇。
第一节摘录中的黑体字是关于朋友声明的内容。如果您有A
和B
这两个类,并且想让B
的特定成员成为A
的朋友,则粗体字表示的是A
必须已经可以访问您指定的特定成员。也就是说,这是非法的:
class B
{
private:
void SomeMember();
};
class A
{
private:
friend void B::SomeMember(); //`SomeMember` is not accessible to `A`, so ill-formed.
};
B
必须使自己成为A
的朋友,以便A
可以命名其私有成员。
第二节摘录中的粗体文本仅表示friend
声明在类中发生的位置无关紧要。 friend
声明是公共的,私有的还是其他无关紧要。也就是说,以下所有内容都表示同一件事:
class B;
class A1
{
public:
friend class B;
};
class A2
{
protected:
friend class B;
};
class A3
{
private:
friend class B;
};
因此,两个粗体摘录彼此无关。
现在,第二节中未加注释的部分实际上用规范性语言说出了第一节摘录中的含义。即,friend
声明中指定的名称必须可访问。
如果我写<...>访问控制是否应用于名称
some_func
?怎么样?
很好。 friend
定义始终定义非成员函数。因此,它们不在类的范围内,因此实际上是public
。因此可以访问。