派生クラスでアクセス制御を強める
Buddy イディオムは我ながら良いアイデアではないかとご機嫌でいろいろ実験していたのですが、今日になって驚くべき事実(つまり、自分の無知)を知ることになりました。
今さらなんですが、C++ ではアクセス制御と継承は直交する概念なんですね。だから、派生クラスでアクセス制御を強めることで、Buddy イディオムと同じことをずっとエレガントに表現することができます。
struct Base { virtual ~Base() {} virtual void DoWork() = 0; }; class Derived : public Base { // おっと、ここはプライベートではないか? virtual void DoWork() { //必要な仕事を行う } public: // ... Derived 固有のインタフェースを実装する }; void DoWork(Base& b) { // もちろん、問題なく実行できる b.DoWork(); } int main() { Derived d; // Base として評価する DoWork(d); // しかし、直接アクセスは禁止しているので、以下はコンパイルできない // d.DoWork(); }
派生クラスでアクセス制御を変更できるというのは直感に反します。でも、冷静に考えてみると、案外、自然なことだとわかりますね。これはシビれるなぁ。インタフェースの不正使用を防ぐ手段としては、最も簡単でスマートな気がします。それともこれはやり過ぎかしら。このコードを見て「ああ、Base のメソッドが不正使用されないようにしてるのね」とすぐに理解できるような人は、少なくとも、僕の周りにはいない気がするなぁ。
なにはともあれ、Buddy イディオムはもう不要なのでした ;-)