在 C++ 物件導向程式設計中,多層繼承是實現程式碼複用與多態的重要機制。動態綁定僅能應用於虛函數,必須透過指標(->)或引用(.)呼叫,其核心在於宣告基類指標並綁定衍生類別物件。
現代 C++ 推薦使用 std::shared_ptr<Abstract_Base_Class> p(new Derived_Class(para)); 形式進行動態綁定,這不僅能自動管理記憶體,還能確保正確的多態行為。為抽象基類新增介面並配合友元函數,可安全存取基類私有成員,將具體操作封裝於介面中。
/*
* 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;
};
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;
};
此範例展示了如何運用多層繼承與智慧指標建立文字查詢系統,體現了 C++ 現代程式設計的最佳實踐。