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

78 Views Asked by At

Here is the code, 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;
}

Compiler is giving the following errors:

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

There are 2 best solutions below

2
On BEST ANSWER

As pewt said, MyClass::func() must be public in order for Access::tryme() to be able to access it. In the example you linked in the comments, Citizen::getSocialSecurityNumber() is actually public. And that is fine, because the access is limited in a different way.

Your MyClass::func() takes a Passkey<Access> parameter – and no one is actually allowed to construct such an object apart from the Access class itself. All of Passkey's functions are private. By construction, Access is the only friend of Passkey<Access>, so only Access can construct the “key” required to call func(). So func() behaves as if it were private, without actually being private itself.

7
On

func() is a private method for MyClass. Access can't call func unless it is made a friend of MyClass.

Making PassKey a friend of Access does not (as far as I know...) allow use of MyClass's private methods.

Via 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.

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