blob: 06ef8918a83fe3e54b77a1aeb1e8e827a8ad9c2d [file] [log] [blame] [view]
Elly Fong-Jones4e3d25c72019-08-12 18:17:151# The Passkey Pattern
2
Elly Fong-Jones0f5259c2019-08-13 14:39:213For the Chromium implementation of this pattern, see
4[//base/util/type_safety/pass_key.h].
5
Elly Fong-Jones4e3d25c72019-08-12 18:17:156The Passkey pattern is used when you need to expose a subset of a class's
7methods to another class in a more granular way than simply friending the other
8class. In essence, it involves creating a "passkey" class that can only be
9constructed by specific other classes, and requiring an instance of that passkey
10class to be passed in when calling methods you wish to restrict the use of. It
11is used like this:
12
13```
14class Foo {
15 public:
16 Foo();
17 ~Foo();
18
19 void NormalPublicMethod();
20 bool AnotherNormalPublicMethod(int a, int b);
21
22 class BarPasskey {
23 private:
24 friend class Bar;
25 BarPasskey() = default;
26 ~BarPasskey() = default;
27 };
28
29 void HelpBarOut(BarPasskey, ...);
30};
31
32...
33
34void Bar::DoStuff() {
35 foo->HelpBarOut(Foo::BarPasskey(), ...);
36}
37```
38
39The private constructor on `Foo::BarPasskey` prevents any class other than `Bar`
40from constructing a `Foo::BarPasskey`, which means that:
41
42* Only `Bar` can call those methods
43* `Bar` can delegate the ability to call those methods to other
44 classes/functions by passing them a `Foo::BarPasskey` instance
45
46This method is effectively free at runtime - a few extra bytes of argument space
47are used to pass in the Passkey object.
48
49It is encouraged to leave the `BarPasskey` parameter unnamed to reinforce that it
50carries no semantic information and is not actually used for anything.
Elly Fong-Jones0f5259c2019-08-13 14:39:2151
52[//base/util/type_safety/pass_key.h]: ../../base/util/type_safety/pass_key.h