天天看点

C++Primer第五版 第十五章习题答案(31~40)

后面的题目主要是进行练习,即使是照搬书本上的例子,也要做一做

31:知识点1:继承体系:is  a ,和has  a 的区别。

知识点2:将层次关系隐藏与接口类之中,保存一个基类(抽象基类)派生类的对象的指针

C++Primer第五版 第十五章习题答案(31~40)

32:

拷贝:调用合成的拷贝构造函数,将智能指针q的内容复制到新对象的对应成员,使智能指针q计数+1

移动:调用合成的移动构造函数,将智能指针q的内容移动到新对象的对应成员,使智能指针q指向NULL

赋值:调用合成的拷贝赋值运算符,将智能指针q的内容替换为参数对象的对应成员的内容,使q计数-1,并让参数计数+1

摧毁:调用合成的析构函数,清理自身,并调用q的析构函数,使计数-1

33:

由于没有数据成员,所以合成的拷贝控制足以应付所有问题

34:

(a): 

1: Query::Query(const std::string& s) 

2: WordQuery::WordQuery(const std::string& s) 

3: AndQuery::AndQuery(const Query& left, const Query& right);

4: BinaryQuery(const Query&l, const Query& r, std::string s);

5: Query::Query(std::shared_ptr<Query_base> query) 2times

6: OrQuery::OrQuery(const Query& left, const Query& right);

7: BinaryQuery(const Query&l, const Query& r, std::string s);

8: Query::Query(std::shared_ptr<Query_base> query) 2times

(b):运算符"<<"会调用Query的rep成员,Query.rep()调用的是OrQuery的rep(因为初始化对象q时使用的是值是"|"运算符返回的Query,而该对象的智能指针q指向的是一个OrQuery对象),而OrQuery并没有定义rep成员,所以直接使用直接基类BinaryQuery的rep成员

(c):q调用的是OrQuery的eval函数,因为是虚函数,且使用引用调用,需动态绑定

35:书上有现成的代码,敲上就行

#ifndef QUERY_H
#define QUERY_H

#include <string>
#include <vector>
#include <set>
#include <map>
using namespace std;
class TextQuery;
//QueryResult保存查询的结果
class QueryResult
{
public:
	typedef vector<string>::size_type line_no;//保存出现的行号,使用类型别名
	friend ostream& operator<<(ostream&, const QueryResult&);//输出查询结果

public:
	QueryResult(const string& s, shared_ptr<std::set<line_no>> set,
		shared_ptr<vector<string>> v)
		: word(s), nos(set), input(v)
	{
	}

private:
	string word;//查询的单词
	shared_ptr<std::set<line_no>> nos;//用set保存出现的行号,自动排序
	shared_ptr<vector<string>> input;//输入文件vector的指针
};

//TextQuery接受输入文件,并保存,生成map
class TextQuery 
{
public:
	/*using line_no = vector<string>::size_type;//C++11新标准,可以使用typedef代替*/
	typedef vector<string>::size_type line_no;

	TextQuery(ifstream&);//接受输入文件的构造函数
	QueryResult query(const string&) const;//具体的查询函数

private:
	shared_ptr<vector<string>> input;//保存输入的vector的智能指针
	map<string, shared_ptr<set<line_no>>> result;//map保存单词出现的行和列
};

//抽象基类Query_base,用于派生
class Query_base
{
	friend class Query;
private:
	//纯虚函数,返回与当前Query匹配的QueryResult
	/*virtual QueryResult eval(const TextQuery&) const = 0;*/
	//纯虚函数,保存用于查询的string
	virtual string rep() const = 0;
protected:
	/*using line_no = vector<string>::size_type;//C++11新标准,可以使用typedef代替*/
	typedef vector<string>::size_type line_no;
	virtual ~Query_base() /*= default*/;//C++11新标准,不加
};

//查询基类 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 string&s);//新的构造函数,查询单词
	//接口函数
// 	QueryResult eval(const TextQuery &t) const
// 	{
// 		return q->eval(t);//查询结果
// 	}//事先无需定义
	string rep() const
	{
		return q->rep();//查询单词
	}
private:
	Query(shared_ptr<Query_base> query):q(query){}//构造函数,接受一个Query_base的指针
	shared_ptr<Query_base> q;//保存一个指向基类的指针,私有成员
};

std::ostream &operator<<(std::ostream &os, const Query query)  
{  
	return os << query.rep();  
} 

//基础查询单词类
class WordQuery:public Query_base
{
	//所有成员皆为private,
	friend class Query;//Query需要使用其构造函数
	WordQuery(const string &s):Query_word(s){cout<<"WordQuery"<<endl;}//初始化

	QueryResult eval(const TextQuery& t) const
	{
		return t.query(Query_word);
	}//纯虚函数,必须重写
	string rep() const
	{
		return Query_word;
	}//纯虚函数,必须重写
	string Query_word;
};
inline Query::Query(const string &s):q(new WordQuery(s)){cout<<"Query"<<endl;}//程序顺序执行,所用之对象必须进行声明

//NotQuery类,取反的query
class NotQuery:public Query_base
{
	friend Query operator~(const Query&);
	NotQuery(const Query&q):query(q){cout<<"NotQuery"<<endl;}//构造函数

	string rep()
	{
		return "~("+query.rep()+")";//表示不需要查询的单词
	}
	QueryResult eval(const TextQuery&);
	Query query;
};
// inline Query operator~(const Query&operand)
// {
// 	return shared_ptr<Query_base>(new NotQuery(operand));
// }

//BinaryQuery类,一个抽象基类,因为继承了基类的纯虚函数eval()
class BinaryQuery:public Query_base
{
protected:
	BinaryQuery(const Query&l, const Query&r,string s):lhs(l),rhs(r),opSym(s){cout<<"BinaryQuery"<<endl;}//构造函数
	string rep() const
	{	cout<<"Binary_rep"<<endl;//36题
		return "("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";
	}
	Query lhs,rhs;
	string opSym;//运算符的名字
};

//AndQuery类,继承自抽象基类BinaryQuery
class AndQuery:public BinaryQuery
{
protected:
	friend Query operator&(const Query&,const Query&);//之前定义的运算符
	AndQuery(const Query&left, const Query&right):BinaryQuery(left,right,"&"){cout<<"AndQuery"<<endl;}//构造函数
	//返回查询结果的函数
	QueryResult eval(const TextQuery&);
};
// inline Query operator&(const Query&lhs, const Query&rhs)
// {
// 	return shared_ptr<Query_base>(new AndQuery(lhs,rhs));//在未定义纯虚函数eval()时,为抽象基类,不可实例化
// }

//OrQuery类,继承自抽象基类BinaryQuery
class OrQuery:public BinaryQuery
{
protected:
	friend Query operator|(const Query&,const Query&);//之前定义的运算符
	OrQuery(const Query&left, const Query&right):BinaryQuery(left,right,"|"){cout<<"OrQuery"<<endl;}//构造函数
	//返回查询结果的函数
	QueryResult eval(const TextQuery&);
};
// inline Query operator|(const Query&lhs, const Query&rhs)
// {
// 	return shared_ptr<Query_base>(new OrQuery(lhs,rhs));
// }

#endif QUERY_H
           

36:见上代码,加一条语句即可

37:

若要含有base类型的成员,应当在派生类中声明 friend class Query_base

38:

(a):错误,Binary_Query是抽象基类,不能实例化

(B):错误,不存在AndQuery到Query之间的转化

(c):同上

39:加上书中的eval函数即可

40:

如果rhs是空集,那么内容到lhs

如果lhs是空集,那么内容为rhs

如果都为空集,那么内容为空

继续阅读