网站的ftp账号和密码是什么,WordPress多域名无法登录,南开区网站建设公司,网站后台账号问题#xff1a;在上一篇继承与多态 文本查询的小例子#xff08;智能指针版本#xff09;在Query类里使用的是智能指针#xff0c;只把智能指针换成普通的指针#xff0c;并不添加拷贝构造方法#xff0c;会发生什么呢#xff1f; 执行时#xff0c;代码崩掉。 分析下…问题在上一篇继承与多态 文本查询的小例子智能指针版本在Query类里使用的是智能指针只把智能指针换成普通的指针并不添加拷贝构造方法会发生什么呢 执行时代码崩掉。 分析下面一行代码: Query qb ~Query(Alice); 1首先调用Query(string)的构造函数把Query的成员q指向了new WordQuery(s) Query::Query(const std::string s) : q(new WordQuery(s)){std::cout Query pub std::endl;
} 2调用WordQuery的构造函数 3调用重载的operator~方法参数是在1处的Query的无名的临时对象 inline Query operator~(const Query op){//return std::shared_ptrQuery_base(new NotQuery(op));std::shared_ptrQuery_base tmp(new NotQuery(op));return Query(tmp);
} 4调用NotQuery的构造方法参数是在1处的Query的无名的临时对象。query(q)是调用了Query的合成的拷贝构造方法所以NotQuery的私有成员query和1处的Query的无名的临时对象的成员q都指向了在2处构建的WordQuery的对象。 NotQuery(const Query q):query(q){std::cout NotQuery std::endl;
} 5return Query(tmp);调用了Query的构造函数又做出了一个Query对象。这个Query的q成员指向了在4处做成的NotQuery对象这个NotQuery对象的query成员的q成员指向了在2处做成的WordQuery对象。 Query(Query_base* qb):q(qb){} 6把在5处做成的Query对象给qb【Query qb ~Query(Alice);】这个时点在1处的Query的无名的临时对象已经没有用了就会释放它就会调用Query的析构函数析构函数会delete p这个p指向的是2处的WordQuery。 接下来执行 print(std::cout, qb.eval(tq)) std::endl; 这时qb的q指向的是4处NotQuery4处的NotQuery的query的q也是指向2处的WordQuery。这时qb去调用eval方法时用qb里的q指向的NotQuery调用eval然后用NotQuery里query的q去调用WorQuery的eval方法可是NotQuery里query的q指向的2处的WordQuery已经被释放程序就蹦了segment core error。 怎么解决 自定义拷贝构造函数。 Query.h #ifndef __QUERY_H__
#define __QUERY_H__#include string
//#include memory
#include iostream
#include TextQuery.hclass QueryResult;
class Query;class Query_base{friend class Query;protected:using line_no TextQuery::line_no;virtual ~Query_base() default;private:virtual QueryResult eval(const TextQuery) const 0;virtual std::string rep() const 0;virtual Query_base* clone() const 0;
};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);//构建一个新的WordQuery~Query(){std::cout Free std::endl;delete q;}Query(const Query tmp){if(tmp ! this){std::cout copy Query std::endl;q tmp.q-clone();}}Query operator(const Query tmp){std::cout Query std::endl;}// 接口函数调用对应的Query_base操作QueryResult eval(const TextQuery t) const{return q-eval(t);}std::string rep()const{return q-rep();}private:/*Query(std::shared_ptrQuery_base query):q(query){std::cout Query pri: std::endl;}*/Query(Query_base* qb):q(qb){}Query_base* q;};class WordQuery : public Query_base{friend class Query;//Query 使用WordQuery的私有构造函数WordQuery(const std::string s): query_word(s){std::cout WordQuery: s std::endl;}QueryResult eval(const TextQuery t)const{return t.query(query_word);}std::string rep()const{return query_word;}virtual WordQuery* clone() const {return new WordQuery(*this);}std::string query_word;
};class NotQuery : public Query_base{friend Query operator~(const Query);NotQuery(const Query q):query(q){//调用Query的拷贝构造函数std::cout NotQuery std::endl;}std::string rep() const {return ~( query.rep() );}virtual NotQuery* clone() const {return new NotQuery(*this);}QueryResult eval(const TextQuery)const;Query query;
};inline Query operator~(const Query op){//return std::shared_ptrQuery_base(new NotQuery(op));Query_base* tmp new NotQuery(op);return Query(tmp);
}class BinaryQuery : public Query_base{protected:BinaryQuery(const Query l, const Query r,std::string s): lhs(l), rhs(r), opSym(s){std::cout BinaryQuery std::endl;}std::string rep() const {return ( lhs.rep() opSym rhs.rep() );}Query lhs, rhs;std::string opSym;
};class AndQuery : public BinaryQuery{friend Query operator(const Query, const Query);AndQuery(const Query l, const Query r): BinaryQuery(l, r, ){std::cout AndQuery std::endl;}QueryResult eval(const TextQuery) const;virtual AndQuery* clone() const {return new AndQuery(*this);}
};inline Query operator(const Query lhs, const Query rhs){return new AndQuery(lhs, rhs);
}class OrQuery : public BinaryQuery{friend Query operator|(const Query, const Query);OrQuery(const Query l, const Query r): BinaryQuery(l, r, |){std::cout OrQuery std::endl;}virtual OrQuery* clone() const {return new OrQuery(*this);}QueryResult eval(const TextQuery) const;
};inline Query operator|(const Query lhs, const Query rhs){return new OrQuery(lhs, rhs);
}#endifQuery.cpp #include Query.h
#include algorithm
#include memory/*
std::ostream operator(std::ostream os, const Query q){//Query::rep通过它的Query_base指针对rep()进行虚调用return os q.rep();
}
*/
Query::Query(const std::string s) : q(new WordQuery(s)){std::cout Query pub std::endl;
}QueryResult NotQuery::eval(const TextQuery text)const{//通过Query运算对象对eval进行虚调用auto result query.eval(text);//开始时结果set为空auto ret_lines std::make_sharedstd::setline_no();auto beg result.begin();auto end result.end();//对于输入文件的每一行如果该行不在result当中则将其添加到ret_linesauto sz result.get_file()-size();for(size_t n 0; n ! sz; n){//如果还没有处理完result的所以行//检查当前行是否存在if(beg end || *beg ! n){ret_lines-insert(n);}else if(beg ! end){beg;//继续获取reslut的下一行}}return QueryResult(rep(), ret_lines, result.get_file());
}QueryResult AndQuery::eval(const TextQuery text)const{//通过Query成员lhs,rhs进行虚调用//调用eval返回每个对象的QueryResultauto right rhs.eval(text);auto left lhs.eval(text);//保存left和right交集的setauto ret_lines std::make_sharedstd::setline_no();//将两个范围的交集写入一个目的迭代其中。std::set_intersection(left.begin(), left.end(),right.begin(), right.end(),inserter(*ret_lines, ret_lines-begin()));return QueryResult(rep(), ret_lines, left.get_file());
}QueryResult OrQuery::eval(const TextQuery text)const{//通过Query成员lhs,rhs进行虚调用//调用eval返回每个对象的QueryResultauto right rhs.eval(text);auto left lhs.eval(text);//将左侧运算对象的行号拷贝到结果set中auto ret_lines std::make_sharedstd::setline_no(left.begin(), left.end());//插入右侧运算对象所得的行号ret_lines-insert(right.begin(), right.end());//返回一个新的QueryResult它表示lhs和rhs的并集return QueryResult(rep(), ret_lines, right.get_file());
}QueryResult.h #ifndef __QUERYRESULT_H__
#define __QUERYRESULT_H__#include iostream
#include set
#include vector
#include string
#include memoryclass QueryResult{friend std::ostream print(std::ostream, const QueryResult);
public:using line_no std::vectorstd::string::size_type;using Iter std::setline_no::iterator;QueryResult(std::string s, std::shared_ptrstd::setline_no p,std::shared_ptrstd::vectorstd::string f):sought(s), lines(p), file(f){}Iter begin() const {return lines-begin();}Iter end() const {return lines-end();}std::shared_ptrstd::vectorstd::string get_file() const{return file;}
private:std::string sought;//查询的单词 std::shared_ptrstd::setline_no lines;//出现的行号 std::shared_ptrstd::vectorstd::string file;
};
//QueryResult类的友元声明
std::ostream print(std::ostream, const QueryResult);#endifTextQuery.h #ifndef __TEXTQUERY_H__
#define __TEXTQUERY_H__#include QueryResult.h
#include map
#include iostream
#include fstream
#include sstream
#include set
#include vector
#include string
#include memoryusing namespace std;
class TextQuery{public:using line_no std::vectorstd::string::size_type;TextQuery(ifstream is); QueryResult query(const std::string sought) const;private:std::shared_ptrstd::vectorstd::string file;std::mapstd::string, std::shared_ptrstd::setline_no wm;
};#endifTextQuery.cpp #include TextQuery.husing namespace std;TextQuery::TextQuery(ifstream is) : file(new vectorstring){string text;while(getline(is, text)){//读文件的每一行 file-push_back(text);int n file-size() - 1;//当前行号 istringstream line(text);//将行文本分解为单词 string word;while(line word){//非常重要必须用引用要不然就会拷贝一个新的set给lines不是原来的 auto lines wm[word];//lines是shared_ptr if(!lines)lines.reset(new setline_no);lines-insert(n);}}
}QueryResult TextQuery::query(const string sought) const{//如果没有找到sought返回指向此set的一个智能指针 static shared_ptrsetline_no nodata(new setline_no);auto ret wm.find(sought);if(ret wm.end()){return QueryResult(sought, nodata, file);//没有找到 }else{return QueryResult(sought, ret-second, file);}
} main.cpp #include Query.h//QueryResult的友元函数
ostream print(ostream os, const QueryResult qr){os qr.sought 出现了 qr.lines-size() 次 endl;for(auto num : *qr.lines){os \t(行号 num 1 ) *(qr.file-cbegin() num) endl;}return os;
}int main(){ifstream infile(/home/ys/cpp/thread/oop/TextQuery/search_text);TextQuery tq(infile);//Query q Query(fiery) Query(bird) | Query(wind);//OK//Query q Query(fiery) | Query(bird);//OK//Query q(Daddy);//OKQuery q ~Query(Alice);//OKprint(std::cout, q.eval(tq)) std::endl;
} 编译方法 g -g Query.cpp TextQuery.cpp main.cpp -stdc11 用于查询的文本文件 Alice Emma has long flowing red hair.
Her Daddy says when the wind blows
through her hair, it looks almost alive,
like a fiery bird in flight.
A beautiful fiery bird, he tells her,
magical but untamed.Daddy , shush, there is no such thing,
she tells him, at the same time wanting
him to tell her more.
Shyly, she asks, I mean, Daddy , is there? Query q Query(fiery) Query(bird) | Query(wind);的执行结果 ((fiery bird) | wind) 出现了2次(行号 2)Her Daddy says when the wind blows(行号 4)like a fiery bird in flight. c/c 学习互助QQ群877684253 本人微信xiaoshitou5854 转载于:https://www.cnblogs.com/xiaoshiwang/p/10252868.html