为什么这段实现 PassKey 模式的代码不能编译?

Why won't this code, implementing PassKey pattern, compile?

这是代码,c++11 :

#include<stdio.h>
#include<iostream>

template<typename T>
class Passkey
{
    friend T;
    Passkey() {}
    Passkey(const Passkey&) {}
    Passkey& operator=(const Passkey&) = delete;
};

class Access;

class MyClass
{
   public:
      MyClass() {}

   private:
      void func(Passkey<Access>) { std::cout<<"here" << std::endl;}
};

class Access
{
    public:
      void tryme(MyClass& c) { c.func(Passkey<Access>());} 
};

int main ()
{
   MyClass c;
   Access a;
   a.tryme(c);
   return 0;
}

编译器给出以下错误:

prog.cpp: In member function 'void Access::tryme(MyClass&)':

prog.cpp:21:12: error: 'void MyClass::func(Passkey<Access>)' is private
           void func(Passkey<Access>) { std::cout<<"here" << std::endl;}
                ^

prog.cpp:27:56: error: within this context
     void tryme(MyClass& c) { c.func(Passkey<Access>());} 

func()MyClassprivate 方法。 Access 不能调用 func 除非它是 MyClassfriend

PassKey 设为 Accessfriend 不允许(据我所知...)使用 MyClassprivate方法。

通过https://en.wikipedia.org/wiki/C%2B%2B_classes#Member_functions

The private members are not accessible outside the class; they can be accessed only through methods of the class.

When should you use 'friend' in C++?

正如 pewt 所说,MyClass::func() 必须是 public 才能使 Access::tryme() 能够访问它。在example you linked in the comments中,Citizen::getSocialSecurityNumber()实际上是public。这很好,因为访问受到不同方式的限制。

你的 MyClass::func() 有一个 Passkey<Access> 参数——而且 除了 Access class 本身,实际上没有人可以构造这样一个对象Passkey的所有功能都是private。通过构造,AccessPasskey<Access> 中唯一的 friend,因此只有 Access 可以构造调用 func() 所需的“密钥”。所以 func() 表现得好像它是私有的,而实际上它本身并不是私有的。