privateメンバへ合法的にアクセス

プライベートは大切にしたいほうです。

このアーティクルを書いている今、個人的な話ですが仕事がデスマーチでプライベートなんてありません。

普段なら、この時期はプライベートジェットでサイパンに飛んで、プライベートビーチに寝転がってiPadでプライベートライアンを見ているはずです。

自分のプライベートが守られない今、他人のクラスのプライベートも守りません。積極的に攻めていくスタイルです。

雇われサラリーマンにも生活があります。

仕事の時間の他に自分の時間も必要なのです。そして、その部分というのは完全にプライベートなのです。

この従業員クラスをもうすこし価値のあるものにしてみましょう。

挨拶できるようになりました。

しかも挨拶する対象の職位に応じて挨拶を変えられます。

例えば

社長の時だけは休暇をせがむようテンプレートを特殊化しました。

 

 

では外部から、このEmployerのprivateメンバにアクセスしてゲームの時間をごっそり仕事の時間に移すことは可能でしょうか。

アクセス指定子の無効化というアーティクルの中で、privateメンバにもアクセスする術について記載しました。あれはC++の言語ルール的にはまったくの違法行為です。

privateというc++のキーワードを再定義してはいけません。

では合法的にやってみましょう。

メンバにテンプレート関数があると、外部でその関数の特殊化を行うことができます。これを利用して本来不可侵だったはずのprivateメンバの内容を意のままに書き換えました。

しかも、アクセス指定子の無効化と違い、今回のアプローチは合法です。特殊化したメンバ関数は、まったく議論の余地がない正式なクラスのメンバ関数ですのでc++の言語ルールに一切抵触していません。

この男は言語ルールの抜け道を知っている法律家だ。彼が捕まることは絶対にない。というのも、彼は法の精神を侵蝕する間も、注意深く条文に従っているからだ

__Exceptional C++ Style アクセス制御の使用と誤用

このアプローチが法に触れそうになる瞬間、それは特殊化に使用した型が既に別の箇所で同様の特殊化に使われており、結果この関数定義がODRに違反する場合です。しかしそれも無名ネームスペースに定義したオリジナルの型を用いることにより簡単に回避することができます。

まとめ

  • あるクラスがテンプレートメンバ関数を持っている場合、内部情報に合法的にアクセスできる
  • ODR違反を回避する為に特殊化に使用する型は無名ネームスペース内で定義する
  • プライベートは大事
Pocket