为什么执行PassKey模式的这段代码无法编译?

时间:2018-08-04 16:54:24

标签: c++ c++11 design-patterns friend-class

代码是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>());} 

2 个答案:

答案 0 :(得分:4)

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

您的MyClass::func()带有一个Passkey<Access>参数–除了Access类本身之外,实际上没有人可以构造这样的对象Passkey的所有功能都是private。通过构造,Accessfriend中唯一的Passkey<Access>,因此只有Access可以构造调用func()所需的“键”。因此func()的行为就好像是私有的,而实际上本身并不是私有的。

答案 1 :(得分:0)

func()private的{​​{1}}方法。除非将MyClass设为Access的{​​{1}},否则func无法调用。{p>

(据我所知……)不允许friend的{​​{1}}的{​​{1}}方法中使用MyClass

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

  

班级以外无法访问私人成员;它们只能通过类的方法进行访问。

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