首页 > 解决方案 > 为什么执行 PassKey 模式的这段代码不能编译?

问题描述

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

标签: c++c++11design-patternsfriend-class

解决方案


正如 pewt 所说,MyClass::func()必须是public为了Access::tryme()能够访问它。在您在评论中链接的示例中Citizen::getSocialSecurityNumber()实际上是public。这很好,因为访问以不同的方式受到限制。

MyClass::func()需要一个Passkey<Access>参数——实际上除了Access类本身之外,没有人被允许构造这样的对象。的所有Passkey功能都是private。通过构造,Access是唯一friendPasskey<Access>,所以只能Access构造调用所需的“键” func()。所以func()表现得好像它是私有的,而不是实际上是私有的。


推荐阅读