【发布时间】:2016-07-21 23:37:22
【问题描述】:
我对编程还很陌生,所以如果答案很明显,请耐心等待我的问题。
在 Lippman、Lajoie 和 Moo 撰写的 C++ Primer 第 5 版的第 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(),因此是可实例化的。
Query类设计如下:
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;
所以我的理解是设计有一个继承层次结构,然后是一个故意相互分离的接口。后者从侧面访问前者,而不是仅仅将基类用作接口。
我有两个问题:
- 没有单独的
Query类有什么问题吗?我们可以只让Query_base类作为层次结构和接口的基础,而去掉Query类吗?我承认正如Query_base所代表的那样,它不能,因为它具有纯虚函数,但这些可以更改。例如,我不能将eval()和rep()的Query函数实现移到Query_base中吗?这样做有什么问题吗?Query中的shared_ptr<Query_base>是否使事情复杂化并且是分离的基础,如果是,我们可以解决这个问题吗? - 这样的层次结构-界面分离有多普遍(如果这是正确的思考方式)?
提前致谢!
【问题讨论】:
-
无继承,Query_base不是Query的基类。尽管有(糟糕的)名称,但这些类之间根本没有关系。否则,
friend关键字是必要的原因。在书中查找“封装”。 -
明确一点:我知道
Query根本不是Query_base继承层次结构的一部分。这就是为什么,正如您所说,friend Query在Query_base类中是必需的。事实上,Query和Query_base之间的这种分离正是我的问题所在。
标签: c++ inheritance interface