设为首页 加入收藏

TOP

c/c++ 继承与多态 文本查询的小例子(非智能指针版本)(一)
2019-01-11 00:14:20 】 浏览:50
Tags:c/c 继承 文本 查询 例子 智能 指针 版本

问题:在上一篇继承与多态 文本查询的小例子(智能指针版本)在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_ptr<Query_base>(new NotQuery(op));
  std::shared_ptr<Query_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;
}

5,return 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.eva l(tq)) << std::endl;

这时qb的q指向的是4处NotQuery,4处的NotQuery的query的q,也是指向2处的WordQuery。这时qb去调用eva l方法时,用qb里的q指向的NotQuery调用eva l,然后用NotQuery里query的q去调用WorQuery的eva l方法,可是NotQuery里query的q指向的2处的WordQuery已经被释放,程序就蹦了(segment core error)。

怎么解决? 自定义拷贝构造函数。

Query.h

#ifndef __QUERY_H__
#define __QUERY_H__

#include <string>
//#include <memory>
#include <iostream>
#include "TextQuery.h"

class QueryResult;
class Query;

class Query_base{
  friend class Query;
 protected:
  using line_no = TextQuery::line_no;
  virtual ~Query_base() = default;
 private:
  virtual QueryResult eva l(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 eva l(const TextQuery& t) const{
    return q->eva l(t);
  }
  std::string rep()const{
    return q->rep();
  }

 private:
  /*
  Query(std::shared_ptr<Query_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 eva l(const TextQuery& t)const{
    return t.query(query_word);
  }
  std::string rep()const{
    return query_word;
  }

  virtual WordQuery* clone() const {
    return new WordQuery(*this);
  }
编程开发网
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c/c++ 继承与多态 文本查询的小例.. 下一篇cf1102F. Elongated Matrix(状压d..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }