私はいくつかの私的な内部構造を持つクラスウィジェットを持っていますが、私はこれらの内部構造を友人関係を介してファンクションツール(唯一)に公開したいと考えています。クラス内部を将来の述語ファンクタに公開するための優れた設計メカニズムですか?
class Widget
{
ComponentA a;
ComponentB b;
friend class WidgetPredicate;
};
class WidgetPredicate : public std::unary_function<bool, const Widget&>
{
bool operator() (const Widget& w) const
{
// inspect a and b and make a yes/no decision
}
};
意図は、私はすべてのstdでふるいとしてWidgetPredicate機能を使用することができます::アルゴリズムの家族xxxx_ifです。
しかし、私は将来、開発者が何らかの形できちんと友人のステータスをinheirit新しい述語を作ることができるシステムで、いくつかの拡張性を残したいと思います。これには良いデザインのイディオムはありますか?私の現在の(非)解決策は、ウィジェットのすべてが公開されていることです。
私は、保護された機能を通じてWidgetPredicateのサブタイプへのウィジェットの内部を露出したベースクラスの周りいじるような何か試してみました:私は今、すべてのクラスはウィジェットの内部を検査する可能性のある潜在的に暮らすことができる
class WidgetPredicate : public std::unary ...
{
protected:
const ComponentA& expose_a (const Widget& w) const { return w.a; }
const ComponentB& expose_b (const Widget& w) const { return w.b; }
public:
virtual bool operator() ...
};
class DerivedWidgetPredicate : public WidgetPredicate
{
public:
virtual bool operator() (const Widget& w)
{
const ComponentA& a = this->expose_a(w); // a can now be inspected/predicated upon
const ComponentB& b = this->expose_b(w); // b ...
}
};
を単に:public WidgetPredicateと言ってください。私は悪意のある開発者から保護しようとしているわけではないので、フレンドリーなWidgetPredicateだと言うと、私はそれを額面で喜んで受け取ります。 構文もsubparですが、私もそれで生きることができます。メンテナンスの問題が気に入らないのですが、ウィジェットの内部を変更するときには、新しいexpose()メソッドをベース述語に追加する必要があります。 (そのプロセスは機械的であり、機械的でなければならない)。
私はいつもWidgetクラスに直接公開する方法を置くことができますが、IMOその時点で私は同様のフィールドを公開する可能性があり、それ(つまり私の現在のSOLN)と一緒に住んでいます。
とても素敵で正確な答えです!私の+1。 –
マイナーノート:BackDoorオブジェクトIIUCを作成するためにプライベートctorとpublic staticファクトリ関数を使用して派生をブロックすることができます。 – Macke
@Marcus Lindblom:継承をブロックする方法はいくつかありますが、これに限定されません。しかし、友情は推移的でも継承的でもないので、私はそれがこの答えにどのように関係しているか分かりません。継承をブロックするもう1つのアプローチは、各コンストラクタに静的メソッドを記述する必要はありません。http://stackoverflow.com/questions/656224/when-should-i-use-c-private-inheritance/656523#656523 –