>>500 私ならインターフェースの継承と実装の継承を分離するかなぁ。
struct FileBase
{
virtual Open() = 0;
virtual Close() = 0;
virtual Read() = 0;
virtual Write() = 0;
virtual ~FileBase() {}
};
struct FileA : public FileBase
{
virtual Seek() = 0;
};
struct FileB : public FileBase
{
virutal Undo() = 0;
};
たとえば、こんな感じでまずインターフェースの階層を作っておく。実装はコンストラクタと
仮想デストラクタ以外は一切無しね。次に、これを継承して実装を作る。
struct FileAImp : public FileA
{
Open();
Close();
...
~FileAImp() { Close(); }
};
struct FileBImp : public FileB
{
Open();
Close();
..
~FileBImp() { Close(); }
};
実装を継承したい場合には、どこかで Close() を書くわけだよね。もし末端のクラスではなく、
途中のクラスで Close() を書いたのなら
- Close() をその先のクラスでオーバーライドしないことに「決め」て、途中のクラスのデストラ
クタで Close() する
- 途中に挟んだクラスのデストラクタでは Close() せずに必ず末端のクラスでのみ Close() する
(ついでに途中に挟んだクラスのデストラクタを protected にして、直接はコンストラクトできない
ように細工)
どちらか好きなほうを選択。どちらにしても、ドキュメントを書いておく。