おことわり
頭悪い初心者のメモです.
謎の話
class Y
と class Z
は class X
が使う何らかの実装として作られた.
//[X.h]
class Y;
class Z;
class X
{
...
private:
Y *m_pY;
Z *m_pZ;
};
この Y
や Z
の具体的な定義というのはどこに書くのか?
こいつらのコードが小規模ならば
//[X.cpp]
#include "X.h"
//じゃあここに書くし
class Y { ... }; //Yの定義
class Z { ... }; //Zの定義
//...以降,Xの実装
とかすれば,とりあえず他所からこの Y
や Z
を使うことはできない(…と思う).
しかし,コード量的に割と邪魔な場合,Y.h
と Y.cpp
とかに分けたくなる.
//[X.cpp]
#include "X.h"
#include "Y.h" //別のところに実装しました
#include "Z.h"
//...以降,Xの実装
でもそうすると,
//[どこか別のコード]
#include "Y.h" //←ヒャッハー! Yを使っちゃうぜ!
...
とかやれちゃう.何か嫌だ.
そしたら,「他所で使う想定じゃねーから」という物は「これらは X
の実装の一部分なので」という話にしておくべきなのか?
class X
{
private:
class Y;
class Z;
};
これなら他所で #include "Y.h"
とかしてみたところで Y
を使おうとすればコンパイラ様がブチギレて阻止してくれる.
しかしこういうスタイル↓というのも考えられるのではあるまいか?
//「YやZを内部クラスとして定義する」だけのやつを別途用意して,
//Xはそいつの友達だということにする.
class Impls
{
friend class X;
private:
Impls() = delete; //このImplsクラス自体はただの入れ物.インスタンスを作れない.
private:
//これらはXからは使える
class Y;
class Z;
};
Y
や Z
を使えるやつを friend
で登録する的な.
一番最初の状態では,Y
と Z
は X
の内部クラスというわけじゃなかったのだから,こっちの方が元々のあるべき姿(?)に近い…のだろうか?
追記
しかし,本当にそこまでして頑なに「使わせない使えない」を達成する必要があるのかい?
例えば,Y
や Z
をいかにも「内部実装ですが何か?」みたいな名称の名前空間にでも突っ込んで,「他所で使う想定じゃねーから」っていう雰囲気だけ示しておけばそれで良くね?
……と,イマジナリーフレンドが脳内に直接意見してくるのであった.