第十五章、面向对象编程
code:
/* 第四部分 面向对象编程与泛型编程 第15章 面向对象编程 15.1 面向对象编程:概述 15.2 定义基类和派生类 15.3 转换与继承 15.4 构造函数和复制控制 15.5 继承情况下的类作用域 15.6 纯虚函数 15.7 容器与继承 15.8 句柄类与继承 15.9 再谈文本查询示例 小结 第15章 面向对象编程 471 15.1 面向对象编程:概述 472 15.2 定义基类和派生类 473 15.2.1 定义基类 474 15.2.2 protected成员 475 15.2.3 派生类 476 15.2.4 virtual与其他成员函数 479 15.2.5 公用、私有和受保护的继承 482 15.2.6 友元关系与继承 486 15.2.7 继承与静态成员 486 15.3 转换与继承 487 15.3.1 派生类到基类的转换 487 15.3.2 基类到派生类的转换 489 15.4 构造函数和复制控制 490 15.4.1 基类构造函数和复制控制 490 15.4.2 派生类构造函数 490 15.4.3 复制控制和继承 494 15.4.4 虚析构函数 495 15.4.5 构造函数和析构函数中的虚函数 497 15.5 继承情况下的类作用域 497 15.5.1 名字查找在编译时发生 498 15.5.2 名字冲突与继承 498 15.5.3 作用域与成员函数 499 15.5.4 虚函数与作用域 500 15.6 纯虚函数 502 15.7 容器与继承 503 15.8 句柄类与继承 504 15.8.1 指针型句柄 505 15.8.2 复制未知类型 507 15.8.3 句柄的使用 508 15.9 再谈文本查询示例 511 15.9.1 面向对象的解决方案 513 15.9.2 值型句柄 514 15.9.3 Query_base类 515 15.9.4 Query句柄类 516 15.9.5 派生类 518 15.9.6 eval函数 520 小结 522 术语 523 */ // 第15章 面向对象编程 // 15.1 面向对象编程:概述 ------------------------------------------------------------------------------------------- // calculate and print price for given number of copies, applying any discounts void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } // 15.2 定义基类和派生类 ------------------------------------------------------------------------------------------- // 15.2.1 定义基类 #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { return n *price; } virtual ~Item_base(){} }; int main() { return 0; } // 15.2.2 protected成员 //派生类只能通过派生类对象访问其基类的 protected 成员, //派生类对其基类类型"对象"的 protected 成员没有特殊访问权限。 void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b) { // attempt to use protected member double ret = price; // ok: uses this->price ret = d.price; // ok: uses price from a Bulk_item object ret = b.price; // error: no access to price from an Item_base } // 15.2.3 派生类 #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } int main() { return 0; } // 15.2.4 virtual与其他成员函数 /* // function with an Item_base reference parameter double print_total(const Item_base &, size_t); Item_base item; // object of base type // ok: use pointer or reference to Item_base to refer to an Item_base object print_total(item, 10); // passes reference to an Item_base object Item_base *p = &item; // p points to an Item_base object Bulk_item bulk; // object of derived type // ok: can bind a pointer or reference to Item_base to a Bulk_item object print_total(bulk, 10); // passes reference to the Item_base part of bulk p = &bulk; // p points to the Item_base part of bulk */ /* 这段代码使用同一基类类型指针指向基类类型的对象和派生类型的对象,该代码还传递基类类型和派生类型的对象来 调用需要基类类型引用的函数,两种使用都是正确的,因为 *** 每个派生类对象都拥有基类部分。 *** */ // calculate and print price for given number of copies, applying any discounts void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } /* Item_base base; Bulk_item derived; // print_total makes a virtual call to net_price print_total(cout, base, 10); // calls Item_base::net_price print_total(cout, derived, 10); // calls Bulk_item::net_price */ #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { cout << "this is Item_base." << endl; // just for test return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { cout << "this is Bulk_item." << endl; // just for test if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } int main() { Item_base base; Bulk_item derived; // print_total makes a virtual call to net_price print_total(cout, base, 10); // calls Item_base::net_price print_total(cout, derived, 10); // calls Bulk_item::net_price return 0; } // ::net.. #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { cout << "this is Item_base." << endl; // just for test return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { cout << "this is Bulk_item." << endl; // just for test if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } int main() { Item_base base; Bulk_item derived; Item_base *baseP = &derived; // calls version from the base class regardless of the dynamic type of baseP double d = baseP->Item_base::net_price(42); return 0; } // 15.2.5 公用、私有和受保护的继承 // 迄今为止,最常见的继承形式是 public。 // using... class Derived : private Base { public: // maintain access levels for members related to the size of the object using Base::size; protected: using Base::n; // ... }; // 15.2.6 友元关系与继承 // 15.2.7 继承与静态成员 // 15.3 转换与继承 ------------------------------------------------------------------------------------------- /* Item_base item; // object of base type Bulk_item bulk; // object of derived type // ok: uses Item_base::Item_base(const Item_base&) constructor Item_base item(bulk); // bulk is "sliced down" to its Item_base portion // ok: calls Item_base::operator=(const Item_base&) item = bulk; // bulk is "sliced down" to its Item_base portion Item_base base; Bulk_item *bulkP = &base; // error: can't convert base to derived Bulk_item &bulkRef = base; // error: can't convert base to derived Bulk_item bulk = base; // error: can't convert base to derived Bulk_item bulk; Item_base *itemP = &bulk; // ok: dynamic type is Bulk_item Bulk_item *bulkP = itemP; // error: can't convert base to derived */ #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { cout << "this is Item_base." << endl; // just for test return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { cout << "this is Bulk_item." << endl; // just for test if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } int main() { Item_base item1; // object of base type Bulk_item bulk1; // object of derived type // ok: uses Item_base::Item_base(const Item_base&) constructor Item_base item2(bulk1); // bulk is "sliced down" to its Item_base portion // ok: calls Item_base::operator=(const Item_base&) item1 = bulk1; // bulk is "sliced down" to its Item_base portion /* Item_base base; Bulk_item *bulkP = &base; // error: can't convert base to derived Bulk_item &bulkRef = base; // error: can't convert base to derived Bulk_item bulk = base; // error: can't convert base to derived Bulk_item bulk; Item_base *itemP = &bulk; // ok: dynamic type is Bulk_item Bulk_item *bulkP = itemP; // error: can't convert base to derived */ return 0; } // 15.4 构造函数和复制控制 ------------------------------------------------------------------------------------------- #include <iostream> #include <string> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { cout << "this is Item_base." << endl; // just for test return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: Bulk_item(const std::string &book, double sales_price, std::size_t qty = 0, double disc_rate = 0.0): Item_base(book, sales_price), min_qty(qty),discount(disc_rate){} // 派生类的初始化列表 // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { cout << "this is Bulk_item." << endl; // just for test if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } int main() { // arguments are the isbn, price, minimum quantity, and discount Bulk_item bulk("0-201-82470-1", 50, 5, .19); return 0; } /* 默认实参 class Bulk_item: public Item_base { public: Bulk_item(const std::string &book, double sales_price, std::size_t qty = 0, double disc_rate = 0.0): Item_base(book, sales_price), min_qty(qty), discount(disc_rate){} // as before }; */ // 15.5 继承情况下的类作用域 ------------------------------------------------------------------------------------------- // 15.6 纯虚函数 ------------------------------------------------------------------------------------------- // 15.7 容器与继承 ------------------------------------------------------------------------------------------- // 15.8 句柄类与继承 ------------------------------------------------------------------------------------------- // 未完成 #include <iostream> #include <string> #include <vector> #include <algorithm> #include <stdexcept> using namespace std; // Item sold at an undiscounted price // derived classes will define various discount strategies class Item_base { private: string isbn; // identifier for the item protected: double price; // normal, undiscounted price public: virtual Item_base *clone()const { return new Item_base(*this); } Item_base(const string &book = "", double sales_price = 0.0): isbn(book), price(sales_price){} string book()const { return isbn; } // returns total sales price for a specified number of items // derived classes will override and apply different discount algorithms virtual double net_price(size_t n)const { cout << "this is Item_base." << endl; // just for test return n *price; } virtual ~Item_base(){} }; // discount kicks in when a specified number of copies of same book are sold // the discount is expressed as a fraction used to reduce the normal price class Bulk_item: public Item_base // 类派生列表 { public: Bulk_item* clone() const { return new Bulk_item(*this); } Bulk_item(const std::string &book, double sales_price, std::size_t qty = 0, double disc_rate = 0.0): Item_base(book, sales_price), min_qty(qty),discount(disc_rate){} // 派生类的初始化列表 // redefines base version so as to implement bulk purchase discount policy double net_price(size_t)const; // 重定义派生类中的虚函数 private: size_t min_qty; // minimum purchase for discount to apply double discount; // fractional discount to apply }; // if specified number of items are purchased, use discounted price double Bulk_item::net_price(size_t cnt)const { cout << "this is Bulk_item." << endl; // just for test if(cnt >= min_qty) return cnt *(1-discount) *price; // price从基类取,protected,可以取到 else return cnt *price; } void print_total(ostream &os, const Item_base &item, size_t n) { os << "ISBN: " << item.book() // calls Item_base::book << "\tnumber sold: " << n << "\ttotal price: " // virtual call: which version of net_price to call is resolved at run time << item.net_price(n) << endl; } // use counted handle class for the Item_base hierarchy class Sales_item { public: // default constructor: unbound handle Sales_item(): p(0), use(new std::size_t(1)){} // attaches a handle to a copy of the Item_base object Sales_item(const Item_base &); // copy control members to manage the use count and pointers Sales_item(const Sales_item &i): p(i.p), use(i.use) { ++ *use; } ~Sales_item() { decr_use(); } Sales_item &operator = (const Sales_item &); // member access operators const Item_base *operator->()const { if(p) return p; else throw std::logic_error("unbound Sales_item"); } const Item_base &operator *()const { if(p) return *p; else throw std::logic_error("unbound Sales_item"); } private: Item_base *p; // pointer to shared item std::size_t *use; // pointer to shared use count // called by both destructor and assignment operator to free pointers void decr_use() { if(-- *use == 0) { delete p; delete use; } } }; // use-counted assignment operator; use is a pointer to a shared use count Sales_item &Sales_item::operator = (const Sales_item &rhs) { ++ *rhs.use; decr_use(); p = rhs.p; use = rhs.use; return *this; } Sales_item::Sales_item(const Item_base &item): p(item.clone()), use(new std::size_t(1)) { } int main() { vector < Item_base > basket; Item_base base; //Bulk_item bulk; Bulk_item bulk("0-201-82470-1", 50, 5, .19); return 0; } // 15.9 再谈文本查询示例 ------------------------------------------------------------------------------------------- // 略 // 这章没有充分理解,因为与STL相关性不大,故先略