私はプログラミングにかなり新しいので、答えが明らかであれば私の質問に耐えます。Lippman's C++ Primerのデザインパターン
Lippman、Lajoie、およびMooのC++ Primer、5th ed。の15.9節では、継承階層のプログラミングが行われています。基本的には抽象クラスQuery_base
で、その子はWordQuery
,NotQuery
、およびBinaryQuery
であり、最後はさらにAndQuery
とOrQuery
に分岐します。 Query_base
階層は、ポインタを介してQuery
というインターフェイスクラスによってアクセスされます。
Query q = Query("fiery") & Query("bird") | Query("wind")
(これらの演算子はQuery_base
型のオブジェクトを指すQuery
オブジェクト、例えばを生成し、「&
」はAndQuery
を生成し、 ':このセットアップの基本的な考え方は、このような化合物のクエリを使用することです~
「NotQuery
を生成します。
テキスト文書は、クエリのルールを満たす行を検索することができます。)
次のようにクラスQuery_baseです:
class Query_base {
friend class Query;
protected:
virtual ~Query_base() = default;
private:
virtual QueryResult eval(const TextQuery&) const = 0;
virtual std::string rep() const = 0;
}
すべてのQuery_baseの子はeval()とrep()を実装するため、インスタンス化できます。
次のようにクラスのクエリが設計されています:
class Query {
friend Query operator~(const Query&);
friend Query operator|(const Query&, const Query&);
friend Query operator&(const Query&, const Query&);
public:
Query(const std::string&);
QueryResult eval(const TextQuery &t) const { return q->eval(t); }
std::string rep() const { return q->rep(); }
private:
Query(std::shared_ptr<Query_base> query) : q(query) { }
std::shared_ptr<Query_base> q;
だから私の理解がデザインはその後、継承階層と故意に互いに分離されているインタフェースを持っていることです。後者は、基底クラスをインタフェースとして提供するのではなく、前者を側からアクセスします。
私は2つの質問があります。
- は別々の
Query
クラスを持っていないに何か問題はありますか?Query_base
クラスを階層のベースとインターフェイスの両方として機能させ、Query
クラスを取り除くことはできますか?私はQuery_base
ということを認識していますが、それは純粋な仮想関数を持っているためできませんが、これらは変更することができます。たとえば、eval()
のQuery
機能とrep()
機能の実装をQuery_base
に移動できませんでしたか?それに何か悪いことはありますか? のQuery
は問題を複雑にし、分離の基礎となりますか?もしそうなら、私たちはその問題を回避できますか? - このような階層インターフェイスの分離があるのはどのくらいですか(これについて考えるのが正しい方法であれば)。事前に
ありがとう!
継承がないため、Query_baseはQueryの基本クラスではありません。 (悪い)名前にもかかわらず、これらのクラスの間には全く関係がありません。さもなければ、 'friend'キーワードが必要であった理由。本の中で "カプセル化"を調べてください。 –
明確にする: 'Query'は' Query_base'継承階層のすべてではないことを理解します。そのため、あなたが言うように、 'Query_base'クラスでは' friend Query'が必要です。実際には、 'Query'と' Query_base'の間のこの分離は私の質問についてです。 – Marron