From 07f636e9b25883a662eb78526b1f526fbc95d1a2 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen Date: Sun, 9 Apr 2017 03:01:48 -0400 Subject: [PATCH 1/2] Add example on Passkey idiom * Fix typos --- 2-patterns/structural/passkey.cpp | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 2-patterns/structural/passkey.cpp diff --git a/2-patterns/structural/passkey.cpp b/2-patterns/structural/passkey.cpp new file mode 100644 index 0000000..38a8929 --- /dev/null +++ b/2-patterns/structural/passkey.cpp @@ -0,0 +1,51 @@ +// Passkey +// C++11 + +class foo { + class Key { + friend class baz; + Key() {} + }; + public: + explicit foo(Key); + + void qux(Key) { + bar(); + } + + private: + void bar(); +}; + +class baz { + public: + void quaz() { + foo f({}); + + f.qux({}); + } +}; + +// Allow granular access to a class' constructors and its methods by +// requiring friendship of a passkey. +// +// Friendship in C++ is all-or-nothing; you cannot share only some +// methods with friendship. The [Passkey +// idiom](https://arne-mertz.de/2016/10/passkey-idiom/) works around that by +// "tagging" exposed methods with a `Key` parameter. If a caller +// class such as `baz` wants to call `foo`'s constructor or methods, +// it must be a friend of `Key`. +// +// The `Key` class defined on [5-8] does not need to be private or +// even defined within `foo`. To disallow `Key` from being created via +// [aggregate initialization](cpp/aggregate_initialization), we must +// explicitly define its default constructor. +// +// The `qux` function ([12-14]) is an example of a method that can +// only be called by `baz`. However, `foo`'s private methods (such as +// `bar()` on [17]) and variables stay private. This demonstrates how +// the Passkey idiom preserves encapsulation. +// +// [23-25] show how the caller would construct `foo` and call its +// member function `qux`. You simply pass a temporary object of type +// `Key` as a parameter using C++11's brace syntax. From ee7d7d30e3a63d6953bb75633ee84f1b56a0ceaa Mon Sep 17 00:00:00 2001 From: Tommy Nguyen Date: Sun, 9 Apr 2017 03:10:27 -0400 Subject: [PATCH 2/2] Remove instances of 'you' --- 2-patterns/structural/passkey.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/2-patterns/structural/passkey.cpp b/2-patterns/structural/passkey.cpp index 38a8929..079ef6f 100644 --- a/2-patterns/structural/passkey.cpp +++ b/2-patterns/structural/passkey.cpp @@ -29,12 +29,12 @@ class baz { // Allow granular access to a class' constructors and its methods by // requiring friendship of a passkey. // -// Friendship in C++ is all-or-nothing; you cannot share only some -// methods with friendship. The [Passkey -// idiom](https://arne-mertz.de/2016/10/passkey-idiom/) works around that by -// "tagging" exposed methods with a `Key` parameter. If a caller -// class such as `baz` wants to call `foo`'s constructor or methods, -// it must be a friend of `Key`. +// Friendship in C++ is all-or-nothing; classes cannot befriend only +// some parts of another class. The [Passkey +// idiom](https://arne-mertz.de/2016/10/passkey-idiom/) works around +// that by "tagging" exposed methods with a `Key` parameter. If a +// caller class such as `baz` wants to call `foo`'s constructor or +// methods, it must be a friend of `Key`. // // The `Key` class defined on [5-8] does not need to be private or // even defined within `foo`. To disallow `Key` from being created via @@ -47,5 +47,5 @@ class baz { // the Passkey idiom preserves encapsulation. // // [23-25] show how the caller would construct `foo` and call its -// member function `qux`. You simply pass a temporary object of type +// member function `qux`. We simply pass a temporary object of type // `Key` as a parameter using C++11's brace syntax.