Chapter 15. Object-Oriented Programming

An Overview

The key ideas in object-oriented programming aredata abstraction,inheritance, and dynamic binding
Using data abstraction, we can define classes that separate interface from implementation (Chapter 7). 
Through inheritance, we can define classes that model the relationships among similar types. 
Through dynamic binding(run-time bingding), we can use objects of these types while ignoring the details of how they differ


class Quote
{
public:
    Quote() = default; //price = 0.0,bookNo = ""
    Quote(const std::string& book,const double sales_price)
    :bookNo(book),price(sales_price){}
    std::string isbn() const{return bookNo;}

    virtual double net_price(const std::size_t n) const {return n*price;}
    virtual ~Quote() = default;  //dynamic binding for the destructor
protected:
    double price = 0.0;
private:
    std::string bookNo;
};
void print_total(std::ostream& os,const Quote &item,std::size_t n)
{
    double ret = item.net_price(n);
    os<<"ISBN: "<<item.isbn()//calls Quote::isbn
    <<"# sold: "<<n<<" total due: "<<ret<<std::endl;
}

class Bluk_quote : public Quote
{
public:
    Bluk_quote() = default;
    Bluk_quote(const std::string& book,const double sales_price,const std::size_t& qty,const double& d)
    :Quote(book,sales_price),min_qty(qty),discount(d){}
    virtual double net_price(std::size_t n) const override
    {
        if(n>=min_qty)
            return n*(1-discount)*price;
        else
            return n*price;
    }

private:
    std::size_t min_qty = 0; //minimum purchase for the discount to apply
    double discount = 0.0;   //fractional discount to display
};

15.2. Defining Base and Derived Classes

15.2.1. Defining a Base Class

note
In C++, dynamic binding happens when a virtual function is called through a reference (or a pointer) to a base class.
note
Base classes ordinarily should define a virtual destructor. Virtual destructors are needed even if they do no work.
note
Member functions that are not declared as virtual are resolved at compile time, not run time.

In C++, a base class must distinguish the functions it expects its derived classes to override from those that it expects its derived classes to inherit without change

What is a virtual member?

A virtual member in a base class expects its derived class define its own version. In particular base classes ordinarily should define a virtual destructor, even if it does no work.

How does the protected access specifier differ from private?

  • private member: base class itself and friend can access
  • protected members: base class itself, friend and derived classes can access

15.2.2. Defining a Derived Class

Virtual Functions in the Derived Class
     Derived classes frequently, but not always, override the virtual functions that they inherit. If a derived class does not override a virtual from its base, then, like any other member, the derived class inherits the version defined in its base class


Derived-Class Objects and the Derived-to-Base Conversion

A derived object contains multiple parts: a subobject containing the (nonstatic) members defined in the derived class itself, plus subobjects corresponding to each base class from which the derived class inherits

Although the standard does not specify how derived objects are laid out in memory, we can think of a Bulk_quote object as consisting of two parts as represented in Figure 15.1

Because a derived object contains subparts corresponding to its base class(es), we can use an object of a derived type as if it were an object of its base type(s). In particular, we can bind a base-class reference or pointer to the base-class part of a derived object.
Quote item; // object of base type
Bulk_quote bulk; // object of derived type
Quote *p = &item; // p points to a Quote object
p = &bulk; // p points to the Quote part of bulk
Quote &r = bulk; // r bound to the Quote part of bulk


The fact that the derived-to-base conversion is implicit means that we can use an
object of derived type or a reference to a derived type when a reference to the base
type is required. Similarly, we can use a pointer to a derived type where a pointer to
the base type is required

note
The fact that a derived object contains subobjects for its base classes is key
to how inheritance works


Derived-Class Constructors

note
Each class controls how its members are initialized
Bulk_quote(const std::string& book, double p,
std::size_t qty, double disc) :
Quote(book, p), min_qty(qty), discount(disc) { }
// as before
};
As with a data member, unless we say otherwise, the base part of a derived object is default initialized. To use a different base-class constructor, we provide a constructor initializer using the name of the base class, followed (as usual) by a parenthesized list of arguments. Those arguments are used to select which base-class constructor to use to initialize the base-class part of the derived object

The base class is initialized first, and then the members of the derived class are initialized in the order in which they are declared in the classs.

The fact that the derived-to-base conversion is implicit means that we can use an
object of derived type or a reference to a derived type when a reference to the base
type is required. Similarly, we can use a pointer to a derived type where a pointer to
the base type is required

The fact that a derived object contains subobjects for its base classes is key
to how inheritance works

Using Members of the Base Class from the Derived Class

A derived class may access the public and protected members of its base class
Key Concept: Respecting the Base-Class Interface 
It is essential to understand that each class defines its own interface. Interactions with an object of a class-type should use the interface of that class, even if that object is the base-class part of a derived object


Inheritance and static Members
If a base class defines a static member (§7.6, p. 300), there is only one such
member defined for the entire hierarchy. Regardless of the number of classes derived
from a base class, there exists a single instance of each static member
class Base
{
public:
    static void statmem();
};
class Derived : public Base
{
    void f(const Derived&);
};
void Derived::f(const Derived &derived_obj)
{
    Base::statmem(); // ok: Base defines statmem
    Derived::statmem(); // ok: Derived inherits statmem
    // ok: derived objects can be used to access static from base
    derived_obj.statmem(); // accessed through a Derived object
    statmem(); // accessed through this object
}
Declarations of Derived Classes
A derived class is declared like any other class (§7.3.3, p. 278). The declaration contains the class name but does not include its derivation list:
class Bulk_quote : public Quote; // error: derivation list can't appear here
class Bulk_quote; // ok: right way to declare a derived class

Classes Used as a Base Class
A class must be defined, not just declared, before we can use it as a base class:
class Quote; // declared but not defined
// error: Quote must be defined
class Bulk_quote : public Quote { ... };

class Base { /* ... */ } ;
class D1: public Base { /* ... */ };
class D2: public D1 { /* ... */ };

Preventing Inheritance
Under the new standard, we can prevent a class from being used as a base by following the class name with final
class NoDerived final { /* */ }; // NoDerived can't be a base class
class Base { /* */ };
// Last is final; we cannot inherit from Last
class Last final : Base { /* */ }; // Last can't be a base class
class Bad : NoDerived { /* */ }; // error: NoDerived is final
class Bad2 : Last { /* */ }; // error: Last is final
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
电子图书资源服务系统是一款基于 Java Swing 的 C-S 应用,旨在提供电子图书资源一站式服务,可从系统提供的图书资源中直接检索资源并进行下载。.zip优质项目,资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目。 本人系统开发经验充足,有任何使用问题欢迎随时与我联系,我会及时为你解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(若有),项目具体内容可查看下方的资源详情。 【附带帮助】: 若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步。 【本人专注计算机领域】: 有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为你提供帮助,CSDN博客端可私信,为你解惑,欢迎交流。 【适合场景】: 相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可以基于此项目进行扩展来开发出更多功能 【无积分此资源可联系获取】 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。积分/付费仅作为资源整理辛苦费用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值