15.1, 15.2, 15.3, 15.5
来源:互联网 发布:程序设计与软件开发 编辑:程序博客网 时间:2024/06/14 05:45
//15.5 Access Control and Inheritance//A derived class member or friend may access the protected members of the base class only through a derived object.class Base {protected: int prot_mem;};class Sneaky : public Base { friend void clobber(Sneaky &); friend void clobber(Base &); int j;};void clobber(Sneaky &s) { s.j = s.prot_mem = 0; }void clobber(Base &b) { b.prot_mem = 0; }//error: clobber can't access the protected members in Base//That function is not a friend of Base, yet it would be allowed to change an object oftype Base; we could circumvent the protection provided by protected for any classsimply by defining a new class along the lines of Sneaky.int main() { return 0;}//public, private, and protected Inheritance//The purpose of the derivation access specifier is to control the access that users of the derived class—including other classes derived from the derived class—have to the members inherited from Base:class Base {public: void pub_mem();protected: int prot_mem;private: char priv_mem;};struct Pub_Derv : public Base { int f() { return prot_mem; } char g() { return priv_mem; }};struct Priv_Derv : private Base { //private derivation doesn't affect access in the derived class int f1() const { return prot_mem; }};//users of derived classint main() { Pub_Derv d1; Priv_Derv d2; d1.pub_mem(); //error: pub_mem is private in the derived class d2.pub_mem();}//classes derived from the derived classclass Base {public: void pub_mem();protected: int prot_mem;private: char priv_mem;};struct Pub_Derv : public Base { int f() { return prot_mem; } //char g() { return priv_mem; }};struct Priv_Derv : private Base { int f1() const { return prot_mem; }};struct Derived_from_Public : public Pub_Derv { int use_base() { return prot_mem; }};struct Derived_from_Private : public Priv_Derv { int use_base() { return prot_mem; }};int main() { return 0;}//Friendship and Inheritanceclass Base { friend class Pal;public: void pub_mem();protected: int prot_mem;private: char priv_mem;};class Sneaky : public Base { friend void clobber(Sneaky &); friend void clobber(Base &); int j;};class Pal {public: int f(Base b) { return b.prot_mem; } //error: Pal is not a friend of Sneaky //int f2(Sneaky s) { return s.j; } //That access includes access to Baseobjects that are embedded in an object of a type derived from Base. int f3(Sneaky s) { return s.prot_mem; }};class D2 : public Pal {public: //error: friendship is not ingerited; each class controls access to its members int mem(Base b) { return b.prot_mem; }};int main() { return 0;}//exempting individual membersclass Base {public: size_t size() const { return n; }protected: size_t n;};class Derived : private Base {public: using Base::size;protected: using Base::n;};//Exercises Section 15.5Exercise 15.18:Base *p = &d1; // d1 has type Pub_Derv legalp = &d2; // d2 has type Priv_Derv illegalp = &d3; // d3 has type Prot_Derv illegalp = &dd1; // dd1 has type Derived_from_Public legalp = &dd2; // dd2 has type Derived_from_Private illegalp = &dd3; // dd3 has type Derived_from_Protected illegalUser code may use the derived-to-base conversion only if D inherits publicly from B.Exercise 15.19:For member functions and friends of D, if inherrits is direct, all can use the derived-to-base conversion, if indirect inherits, only private can not.Hence, below are legal.pub_derv.priv_derv.prot_derv.derived_from_public.derived_from_public.derived_from_protected.Exercise 15.20:class Base {public: void pub_mem();protected: int prot_mem;private: char priv_mem;};struct Pub_Derv : public Base { void memfcn(Base &b) { b = *this; }};struct Priv_Derv : private Base { void memfcn(Base &b) { b = *this; }};struct Prot_Derv : protected Base { void memfcn(Base &b) { b = *this; }};struct Derived_from_Public : public Pub_Derv { void memfcn(Base &b) { b = *this; }};struct Derived_from_Private : public Priv_Derv { //void memfcn(Base &b) { b = *this; }};struct Derived_from_Protected : public Prot_Derv { void memfcn(Base &b) { b = *this; }};int main() { Pub_Derv d1; Base *p = &d1; Priv_Derv d2; //p = &d2; Prot_Derv d3; //p = &d3; Derived_from_Public dd1; p = &dd1; Derived_from_Private dd2; //p = &dd2; Derived_from_Private dd3; //p = &dd3; return 0;}Exercise 15.21:class Shape {public: using Coordinate = pair<double, double>; Shape() = default; Shape(const string &n) : name(n) { } virtual double area() const = 0; virtual double perimeter() const = 0; virtual ~Shape() = default;private: string name;};class Rectangle : public Shape {public: Rectangle() = default; Rectangle(const string &n, const Coordinate &a, const Coordinate &b, const Coordinate &c, const Coordinate &d) : shape(n), a(a), b(b), c(c), d(d) { } ~Rectangle() = default;protected: Coordinate a, b, c, d;};class Square : public Rectangle {public: Square() = default; Square(const string &n, const Coordinate &a, const Coordinate &b, const Coordinate &c, const Coordinate &d) : Rectangle(n, a, b, c, d) { } ~Square() = default;};int main() { return 0;}
//15.1. OOP: An Overview//15.2. Defining Base and Derived Classesclass Quote {public: Quote() = default; Quote(const string &book, double sales_price): bookNo(book), price(sales_price) { } string isbn() const { return bookNo; } virtual double net_price(size_t n) const { return n * price; } virtual ~Quote() = default;private: string bookNO;protected: double price = 0.0;};class Bulk_quote : public Quote {public: double net_price(size_t) const override;};double print_total(ostream &os, const Quote &item, size_t n) { double ret = item.net_price(n); os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl; return ret;}int main() { print_total(cout, basic, 20); print_total(cout, bulk, 20);}Exercises Section 15.2.1Exercise 15.1://A virtual member in a base class expects ites derived class define its own version. In particular base classes ordinarily should define a virtual destructor, even if it does no work.Exercise 15.2://private member: base class itset and friend can access//protected members: base class itself, friend and derived classes can access//Inheritance and static Membersclass Base {public: static void statmem() { }};class Derived : public Base { void f(const Derived &);};void Derived::f(const Derived &derived_obj) { Base::statmem(); Derived::statmem(); derived_obj.statmem(); statmem();}int main() { return 0; }//Declarations of Derived Classes//The derivation list, and all other details of the definition, must appear together in the class body.class Bulk_quote : public Quote;class Bulk_quote;//A class must be defined, not just declared, before we can use it ans a base classclass Quote;class Bulk_quote : public Quote { };int main() { return 0; }//A base class can itself be a derived class:class Base { };class D1 : public Base { };class D2 : public D1 { };//Preventing Inheritanceclass NoDerived final { };class Base { };class Last final : Base { };class Bad : NoDerived { };//errorclass Bad2 : Last { };//errorint main() { return 0; }Exercises Section 15.2.2//Exercise 15.4: Which of the following declarations, if any, are incorrect? Explain why.class Base { ... };(a) class Derived : public Derived { ... };//incorrect, derived itself(b) class Derived : private Base { ... };//incorrect, it is a defination not a declaration(c) class Derived : public Base;//incorrect, A derived class is declared like any other class. The declaration contains the class name but does not include its derivation list.//Exercise 15.5: Define your own version of the Bulk_quote class.//Exercise 15.6: Test your print_total function from the exercises in §15.2.1 (p. 595) by passing both Quote and Bulk_quote objects o thatfunction.//Exercise 15.7: Define a class that implements a limited discount strategy, which applies a discount to books purchased up to a given limit. If the number of copies exceeds that limit, the normal price applies to those purchased beyond the limit.class Quote {public: Quote() = default; Quote(const string &book, double sales_price): bookNo(book), price(sales_price) { } string isbn() const { return bookNo; } virtual double net_price(size_t n) const { return n * price; } virtual ~Quote() = default;private: string bookNo;protected: double price = 0.0;};class Bulk_quote : public Quote {public: Bulk_quote() = default; Bulk_quote(const string &book, double p, size_t qty, double dis) : Quote(book, p), min_qty(qty), discount(dis) { } double net_price(size_t cnt) const override { if(cnt >= min_qty) return cnt * (1 - discount) * price; else return cnt * price; }private: size_t min_qty = 0; double discount = 0.0;};double print_total(ostream &os, const Quote &item, size_t n) { double ret = item.net_price(n); os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl; return ret;}class Limited_quote : public Bulk_quote {public: Limited_quote() = default; Limited_quote(const string &book, double p, size_t qty, double dis, int n): Bulk_quote(book, p, qty, dis), lim_n(n) { } double net_price(size_t n) const override { if(n <= lim_n) return Bulk_quote::net_price(n); else return Bulk_quote::net_price(lim_n) + Quote::net_price(n-lim_n); }private: unsigned int lim_n;};int main() { Quote basic("12-34-45678", 10); Bulk_quote bulk("12-34-45678", 10, 10, 0.2); Limited_quote limit("12-34-45678", 10, 10, 0.2, 10); print_total(cout, basic, 10); print_total(cout, bulk, 10); print_total(cout, limit, 11); return 0;}//There Is No Implicit Conversion from Base to Derivedclass Quote { };class Bulk_Quote : public Quote { };int main() { Quote base; Bulk_Quote *bulkp = &base; //error cannot convert 'Quote*' to 'Bulk_Quote' Bulk_Quote &bulkRef = base;//error invalid inititalization of reference of type 'Bulk_Quote&' from 'Quote' return 0;}//we cannot convert from base to derived even when a base pointer or reference is bound to a derived objectclass Quote { };class Bulk_Quote : public Quote { };int main() { Bulk_Quote bulk; Quote *itemP = &bulk; Bulk_Quote *bulkP = itemP; return 0;}//Exercises Section 15.2.3//Exercise 15.8: Define static type and dynamic type.//The static type of an expression is always known at compile time//The dynamic type is the type of the object in memory that the variable or expression represents. May be know at run-time//Exercise 15.9: When is it possible for an expression¡¯s static type to differ from its dynamic type? Give three examples in which the static and dynamictype differ.//the static type of a pointer or reference to a base classs may differ from its dynamic type //Exercise 15.10: Recalling the discussion from ¡ì8.1 (p. 311), explain howthe program on page 317 that passed an ifstream to the Sales_dataread function works.
15.3. Virtual Functions//override and final specifierstruct B { virtual void f1(int) const; virtual void f2(); void f3();};struct D1 : B { void f1(int) const override; //void f2(int) override; //void f3() override; //void f4() override;};struct D2 : B { void f1(int) const final;};struct D3 : D2 { void f2(); void f1(int) const;};Exercises Section 15.3//Exercise 15.11: Add a virtual debug function to your Quote class hierarchy//that displays the data members of the respective classes.class Quote {public: Quote() = default; Quote(const string &book, double sales_price): bookNo(book), price(sales_price) { } string isbn() const { return bookNo; } virtual void debug() const { cout << "bookNo = " << bookNo << " " << " price = " << price << " "; } virtual double net_price(size_t n) const { return n * price; } virtual ~Quote() = default;private: string bookNo;protected: double price = 0.0;};class Bulk_quote : public Quote {public: Bulk_quote() = default; Bulk_quote(const string &book, double p, size_t qty, double dis) : Quote(book, p), min_qty(qty), discount(dis) { } void debug() const override { cout << "min_qty = " << min_qty << " " << "discount = " << discount << " "; } double net_price(size_t cnt) const override { if(cnt >= min_qty) return cnt * (1 - discount) * price; else return cnt * price; }private: size_t min_qty = 0; double discount = 0.0;};double print_total(ostream &os, const Quote &item, size_t n) { double ret = item.net_price(n); os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl; return ret;}void print_debug(const Quote& q) { q.debug(); }int main() { Quote q("12-34-45678", 10); Bulk_quote bq("22-34-45678", 20, 10, 0.2); //no dynamic binding Quote &r = q; r.debug(); cout << endl; r = bq; r.debug(); cout << endl; cout << "=====================\n"; //dynamic binding print_debug(q); cout << endl; print_debug(bq); cout << endl; return 0;}//Exercise 15.12: Is it ever useful to declare a member function as both//override and final? Why or why not?//Sure. override mean overriding the virtual function in base class. final is just for the lower classes at the hierarchy.//Exercise 15.13: Given the following classes, explain each print function://If there is a problem in this code, how would you fix it?class base {public: string name() { return basename; } virtual void print(ostream &os) { os << basename; }private: string basename = "base\n";};class derived : public base {public: void print(ostream &os) override { base::print(os); os << "derived\n" << i; }private: int i = 0;};int main() { base b; derived d; b.print(cout); d.print(cout); return 0;}//Exercise 15.14: Given the classes from the previous exercise and the//following objects, determine which function is called at run time:/*base bobj; base *bp1 = &bobj; base &br1 = bobj;derived dobj; base *bp2 = &dobj; base &br2 = dobj;(a) bobj.print();(b) dobj.print();(c) bp1->name();(d) bp2->name();(e) br1.print();(f) br2.print();*/class base {public: base(const string &s) : basename(s) { } string name() { return basename; } virtual void print(ostream &os) { os << basename << endl; }private: string basename;};class derived : public base {public: derived(const string &s, int i) : base(s), i(i) { } void print(ostream &os) override { base::print(os); os << " " << i << endl; }private: int i = 0;};int main() { base bobj("bobj"); base *bp1 = &bobj; base &br1 = bobj; derived dobj("dobj", 10); base *bp2 = &dobj; base &br2 = dobj; //compile bobj.print(cout); dobj.print(cout); //compile cout << bp1->name() << endl; cout << bp2->name() << endl; //run time br1.print(cout); br2.print(cout); return 0;}
阅读全文
0 0
- 15.1, 15.2, 15.3, 15.5
- !!!Chapter 15 Object-Oriented Programming (15.3 ~ 15.5)
- !!!Chapter 15 Object-Oriented Programming (15.1 ~ 15.2)
- 15.5
- 15.3
- PBRT阅读:第十五章 蒙特卡罗积分 2: 提高效率 (第15.1-15.5节)
- 15.2
- 15.2
- 15.2
- 八周三次课(12月13日) 15.1 多线程实例 15.2 多线程锁
- 15.1
- 15.1
- 15.1
- 15.3.1
- 15.3Sum
- 15.3Sum
- 15.3.3
- 15.3sum
- jqGrid 帮助文档
- spring boot(8)-mybatis三种动态sql
- 网上的画板代码收集和整理
- hdu5578_Friendship of Frog_思维
- Spring 给bean配置list<bean>列表参数
- 15.1, 15.2, 15.3, 15.5
- Git 笔记
- 在jsp中用ajax向action传值为空 JSP中确定有值
- MVP+Retrofit+RxJava+Okhttp拦截器
- Ubuntu 搜索文件的方法
- NUC1013 阶乘结果末尾有多少零【分析思维】
- AMD phenom(翼龙) x4 955 黑苹果(El Capital 10.11.6)安装成功记录
- 利用jQuery load 方法加载HTML公共页面,导航菜单自动选中
- 【实验楼系列】【makefile】编译,链接基础实验