没有长时间的延迟,这里的代码我不知道它为什么会这样做:
#include <iostream>
class A {
private:
void print() { std::cout << "A.print() called" << std::endl; };
public:
template<typename Foo>
class B; //NOTE: no friend!
public:
A();
B<double>* bd;
B<int>* bi;
};
template<typename Foo>
class A::B{
A* callback;
public:
B(A* a):callback(a){};
void print() { callback->print(); }; // Why is this working ???
};
A::A():bd(new B<double>(this)),bi(new B<int>(this)){}
int main(int argc, char **argv)
{
A a;
// a.print(); // error: ‘void A::print()’ is private
a.bd->print();
a.bi->print();
A::B<char> c(&a);
c.print();
A::B<double> d = *a.bd;
d.print();
return 0;
}
嗯,它创造了这个输出:
A.print() called
A.print() called
A.print() called
A.print() called
但为什么?
当我遇到与friend
s有关的问题时,我最初开始了我的兔子洞之旅。我读了friend declaration not forward declaring(以及提到的答案here和here)。因此,在尝试设置一个简单示例(您在上面看到的结果)时,我发现我实际上根本不需要friend
。
以下是底线问题:为什么A::B
的实例可以访问A
的私有函数A::print()
?(尽管我这样做)意识到我可能会误解my children是什么 - 孩子而不是基础与派生)
答案 0 :(得分:2)
嵌套类(或内部类)可以访问嵌套在其中的类的私有。从某种意义上说,它已经是那个班级的朋友了。它类似于任何A
对象可以访问任何其他A
对象的私有的方式。
对于要在其类外部定义的要访问其私有的类,可以使用friend
。这是一个简单的例子:
struct B;
class A
{
int x;
friend struct B;
};
struct B
{
void someFunc() {
A a;
a.x = 5;
}
};
int main(int argc, const char* argv[])
{
B b;
b.someFunc();
return 0;
}
如果B
成为A
的朋友,则无法访问A
成员x
。
答案 1 :(得分:2)
因为嵌套类是封闭类的成员
标准$ 11.7.1
“嵌套类是一个成员,因此具有与任何其他成员相同的访问权限。封闭类的成员对嵌套类的成员没有特殊访问权限;应遵守通常的访问规则”
和通常的访问规则指定:
“类的成员也可以访问该类有权访问的所有名称......”
标准中给出了具体的例子:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
}