C++中多層繼承(inheritance) 的使用及樣本

來源:互聯網
上載者:User

動態綁定只能應用在虛函數(virtual function), 通過指標(->)或引用(.)調用; 聲明基類指標, 綁定衍生類別對象;

可以使用"shared_ptr<Abstract_Base_Class> p(new Derived_Class(para));"的形式, 動態綁定派生的類;

可以為動態基類添加一個介面(interface), 使用友元函數, 訪問基類的私人成員變數; 並把具體操作寫入介面中;

如果一個衍生類別, 沒有實現抽象基類的純虛函數, 則會繼承此函數, 那麼這個衍生類別也是抽象基類;

抽象基類不能建立具體的對象, 但是可以實現具體的方法, 為衍生類別提供繼承;

物件導向編程: 抽象(abstraction), 即資料抽象(data abstraction);繼承(inheritance);多態(polynorphism), 即動態綁定(dynamic binding).

具體代碼如下, 詳見注釋:

/*  * cppprimer.cpp  *  *  Created on: 2013.11.7  *      Author: Caroline  */      /*eclipse cdt, gcc 4.8.1*/      #include <iostream>  #include <fstream>  #include <sstream>  #include <string>  #include <vector>  #include <memory>  #include <algorithm>  #include <iterator>        #include <set>  #include <map>        using namespace std;        class QueryResult;  std::ostream& print(std::ostream& os, const QueryResult &qr);        class TextQuery {  public:      using line_no = std::vector<std::string>::size_type;      TextQuery(std::ifstream& );      QueryResult query(const std::string& ) const;  private:      std::shared_ptr<std::vector<std::string> > file; //檔案內容      std::map<std::string, std::shared_ptr<std::set<line_no> > > wm; //詞和行號的集合  };        /*把每一行放入text, 存入file(vector), 組成word和行號(set)的映射*/TextQuery::TextQuery(std::ifstream &is) : file(new std::vector<std::string>)  {      std::string text;      while (std::getline(is, text)) {          file->push_back(text);          int n = file->size() - 1;          std::istringstream line(text);          std::string word;          while (line >> word) {              auto& lines = wm[word];              if (!lines)                  lines.reset(new set<line_no>);              lines->insert(n);          }      }  }        class QueryResult {  friend std::ostream& print (std::ostream&, const QueryResult& );  public:      using line_no = std::vector<std::string>::size_type;      QueryResult (std::string s, //查詢單詞              std::shared_ptr<std::set<line_no>> p, //匹配行號              std::shared_ptr<std::vector<std::string>> f) : //輸入檔案                  sought(s), lines(p), file(f) {}      std::set<line_no>::iterator begin() { return lines->begin(); }      std::set<line_no>::iterator end() { return lines->end(); }      std::shared_ptr<std::vector<std::string>> get_file() { return file; }  private:      std::string sought; //尋找字串      std::shared_ptr<std::set<line_no>> lines; //行號集合      std::shared_ptr<std::vector<std::string>> file; //檔案集合  };        /*找到指定sought的集合, 返回迭代器, 傳入string和set*//*更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/*/QueryResult TextQuery::query(const std::string& sought) const {      static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);      auto loc = wm.find(sought);      if (loc == wm.end())          return QueryResult(sought, nodata, file); //沒有找到, 不列印      else        return QueryResult(sought, loc->second, file); //按行號列印  };        std::string make_plural (std::size_t ctr, const std::string& word,          const std::string ending)  {      return (ctr > 1) ? word + ending : word;  }        std::ostream& print(std::ostream& os, const QueryResult &qr){      os << qr.sought << " occurs " << qr.lines->size() << " "            << make_plural(qr.lines->size(), "time", "s") << std::endl;      for(auto num : *qr.lines)          os << "\t(line " << num+1 << ") " << *(qr.file->begin()+num) << std::endl;      return os;  }        void runQueries (std::ifstream &infile) {      TextQuery tq(infile);      while (true) {          std::cout << "enter word to look for, or q to quit: ";          std::string s;          if ( !(cin>>s) || s == "q" ) break;          print(std::cout, tq.query(s)) << std::endl;      }  }        /*抽象基類, 沒有public成員*/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;  };        //為Query_base提供介面(interface)  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(); } //產生string版本的查詢  private:      Query(std::shared_ptr<Query_base> query) : q(query) {}      std::shared_ptr<Query_base> q; //使用動態綁定  };        //重載輸出(<<)操作符  std::ostream & operator<<(std::ostream &os, const Query &query)  {      return os << query.rep();  }        //單詞查詢類  class WordQuery : public Query_base {      friend class Query;      WordQuery (const std::string &s) : query_word (s) {}      QueryResult eval (const TextQuery &t) const { return t.query(query_word); }      std::string rep() const { return query_word; };      std::string query_word;  };        //Query介面實現動態綁定WordQuery  inline Query::Query (const std::string &s) : q(new WordQuery(s)) {}        //取反查詢  class NotQuery : public Query_base {      friend Query operator~ (const Query &); //友元是取反函數      NotQuery (const Query &q) : query(q) {}      std::string rep() const {return "~("+query.rep()+")";}      QueryResult eval (const TextQuery &t) const;      Query query;  };        //實現取反操作, 動態綁定NotQuery對象  //最終使用的是WordQuery類, Query構建需要WordQuery, 再傳入NotQuery;  inline Query operator~ (const Query &operand) {      return std::shared_ptr<Query_base> (new NotQuery(operand));  }        //二元查詢, 沒有eval, 則繼承純虛函數  class BinaryQuery : public Query_base {  protected:      BinaryQuery (const Query &l, const Query &r, std::string s) :          lhs(l), rhs(r), opSym(s) {}      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& left, const Query& right) : BinaryQuery (left, right, "&") {}      QueryResult eval (const TextQuery&) const;  };        inline Query operator& (const Query& lhs, const Query& rhs) {      return std::shared_ptr<Query_base>(new AndQuery(lhs, rhs));  }        //取或查詢  class OrQuery : public BinaryQuery {      friend Query operator| (const Query&, const Query&);      OrQuery (const Query& left, const Query& right) : BinaryQuery (left, right, "|") {}      QueryResult eval (const TextQuery&) const;  };        inline Query operator| (const Query& lhs, const Query& rhs) {      return std::shared_ptr<Query_base>(new OrQuery(lhs, rhs));  }        QueryResult OrQuery::eval(const TextQuery& text) const {      auto right = rhs.eval(text), left = lhs.eval(text);      auto ret_lines = std::make_shared<std::set<line_no> >(left.begin(), left.end());      ret_lines->insert(right.begin(), right.end());      return QueryResult(rep(), ret_lines, left.get_file());  }        QueryResult AndQuery::eval(const TextQuery& text) const {      auto left = lhs.eval(text), right = rhs.eval(text); //調用的是WordQuery的eval      auto ret_lines = std::make_shared<std::set<line_no>>();      std::set_intersection(left.begin(), left.end(), right.begin(), right.end(),              std::inserter(*ret_lines, ret_lines->begin()));      return QueryResult(rep(), ret_lines, left.get_file());  }        QueryResult NotQuery::eval(const TextQuery& text) const{      auto result = query.eval(text); //調用WordQuery.eval;      auto ret_lines = std::make_shared<std::set<line_no>>();      auto beg = result.begin(), end = result.end();      auto sz = result.get_file()->size();      for (size_t n=0; n!=sz; ++n) {          if (beg==end || *beg != n )              ret_lines->insert(n);          else if (beg!=end)              ++beg;      }      return QueryResult(rep(), ret_lines, result.get_file());  }        bool get_word(std::string& str) {      std::cout << "enter word to look for, or q to quit: " << std::endl;      if ( !(std::cin >> str) || str == "q" ){          std::cout << str;          return false;      }      else{          std::cout << str;          return true;      }  }        int main (void) {            std::ifstream infile;      infile.open("storyDataFile.txt");      TextQuery file = infile;      //Query q = ~Query("Alice");      //Query q = Query("hair") | Query("Alice");      //Query q = Query("hair") & Query("Alice");      Query q = Query("fiery") & Query("bird") | Query("wind");      const auto results = q.eval(file);      cout << "\nExecuting Query for: " << q << endl;      print(cout, results) << endl;      infile.close();      return 0;        }

輸出:

Executing Query for: ((fiery & bird) | wind)  ((fiery & bird) | wind) occurs 3 times      (line 2) Her Daddy says when the wind blows       (line 4) like a fiery bird in flight      (line 5) A beautiful fiery bird he tells her

作者:csdn部落格 Spike_King

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。