1、二 九 届 毕 业 设 计翻译资料学 院: 专 业: 姓 名: 学 号:指导教师: 完成时间: 二九年三月Object-Oriented ProgrammingObject-oriented programming is based on three fundamental concepts: data abstraction, inheritance, and dynamic binding. In C+ we use classes for data abstraction and class derivation to inherit one class from another: A
2、derived class inherits the members of its base class(es). Dynamic binding lets the compiler determine at run time whether to use a function defined in the base or derived class.Inheritance and dynamic binding streamline our programs in two ways: They make it easier to define new classes that are sim
3、ilar, but not identical, to other classes, and they make it easier for us to write programs that can ignore the details of how those similar types differ.。Many applications are characterized by concepts that are related but slightly different. For example, our bookstore might offer different pricing
4、 strategies for different books. Some books might be sold only at a given price. Others might be sold subject to some kind of discount strategy. We might give a discount to purchasers who buy a specified number of copies of the book. Or we might give a discount for only the first few copies purchase
5、d but charge full price for any bought beyond a given limit. Object-oriented programming (OOP) is a good match to this kind of application. Through inheritance we can define types that model the different kinds of books. Through dynamic binding we can write applications that use these types but that
6、 can ignore the type-dependent differences. The ideas of inheritance and dynamic binding are conceptually simple but have profound implications for how we build our applications and for the features that programming languages must support. Before covering how C+ supports OOP, well look at the concep
7、ts that are fundamental to this style of programming.An OverviewThe key idea behind OOP is polymorphism. Polymorphism is derived from a Greek word meaning “many forms.“ We speak of types related by inheritance as polymorphic types, because in many cases we can use the “many forms“ of a derived or ba
8、se type interchangeably. As well see, in C+, polymorphism applies only to references or pointers to types related by inheritance. InheritanceInheritance lets us define classes that model relationships among types, sharing what is common and specializing only that which is inherently different. Membe
9、rs defined by the base class are inherited by its derived classes. The derived class can use, without change, those operations that do not depend on the specifics of the derived type. It can redefine those member functions that do depend on its type, specializing the function to take into account th
10、e peculiarities of the derived type. Finally, a derived class may define additional members beyond those it inherits from its base class. Classes related by inheritance are often described as forming an inheritance hierarchy. There is one class, referred to as the root, from which all the other clas
11、ses inherit, directly or indirectly. In our bookstore example, we will define a base class, which well name Item_base, to represent undiscounted books. From Item_base we will inherit a second class, which well name Bulk_item, to represent books sold with a quantity discount. At a minimum, these clas
12、ses will define the following operations: an operation named book that will return the ISBN an operation named net_price that returns the price for purchasing a specified number of copies of a bookClasses derived from Item_base will inherit the book function without change: The derived classes have
13、no need to redefine what it means to fetch the ISBN. On the other hand, each derived class will need to define its own version of the net_price function to implement an appropriate discount pricing strategy. In C+, a base class must indicate which of its functions it intends for its derived classes
14、to redefine. Functions defined as virtual are ones that the base expects its derived classes to redefine. Functions that the base class intends its children to inherit are not defined as virtual. Given this discussion, we can see that our classes will define three (const) member functions: A nonvirt
15、ual function, std:string book(), that returns the ISBN. It will be defined by Item_base and inherited by Bulk_item. Two versions of the virtual function, double net_price(size_t), to return the total price for a given number of copies of a specific book. Both Item_base and Bulk_item will define thei
16、r own versions of this function.Dynamic BindingDynamic binding lets us write programs that use objects of any type in an inheritance hierarchy without caring about the objects specific types. Programs that use these classes need not distinguish between functions defined in the base or in a derived c
17、lass.For example, our bookstore application would let a customer select several books in a single sale. When the customer was done shopping, the application would calculate the total due. One part of figuring the final bill would be to print for each book purchased a line reporting the total quantit
18、y and sales price for that portion of the purchase.We might define a function named print_total to manage this part of the application. The print_total function, given an item and a count, should print the ISBN and the total price for purchasing the given number of copies of that particular book. Th
19、e output of this function should look like: ISBN: 0-201-54848-8 number sold: 3 total price: 98ISBN: 0-201-82470-1 number sold: 5 total price: 202.5Our print_total function might look something like the following: / calculate and print price for given number of copies, applying any discountsvoid prin
20、t_total(ostream / ok: uses price from a Bulk_item objectret = b.price; / error: no access to price from an Item_baseThe use of d.price is okay, because the reference to price is through an object of type Bulk_item. The use of b.price is illegal because Bulk_item has no special access to objects of t
21、ype Item_base.Derived ClassesTo define a derived class, we use a class derivation list to specify the base class(es). A class derivation list names one or more base classes and has the formclass classname: access-label base-classwhere access-label is one of public, protected, or private, and base-cl
22、ass is the name of a previously defined class. As well see, a derivation list might name more than one base class. Inheritance from a single base class is most common and is the topic of this chapter. Well have more to say about the access label used in a derivation list in Section 15.2.5 (p. 570).
23、For now, whats useful to know is that the access label determines the access to the inherited members. When we want to inherit the interface of a base class, then the derivation should be public. A derived class inherits the members of its base class and may define additional members of its own. Eac
24、h derived object contains two parts: those members that it inherits from its base and those it defines itself. Typically, a derived class (re)defines only those aspects that differ from or extend the behavior of the base. Defining a Derived ClassIn our bookstore application, we will derive Bulk_item
25、 from Item_base, so Bulk_item will inherit the book, isbn, and price members. Bulk_item must redefine its net_price function and define the data members needed for that operation: / discount kicks in when a specified number of copies of same book are sold/ the discount is expressed as a fraction use
26、d to reduce the normal priceclass Bulk_item : public Item_base public:/ redefines base version so as to implement bulk purchase discount policydouble net_price(std:size_t) const;private:std:size_t min_qty; / minimum purchase for discount to applydouble discount; / fractional discount to apply;Each B
27、ulk_item object contains four data elements: It inherits isbn and price from Item_base and defines min_qty and discount. These latter two members specify the minimum quantity and the discount to apply once that number of copies are purchased.Derived Classes and virtual FunctionsOrdinarily, derived c
28、lasses redefine the virtual functions that they inherit, although they are not requried to do so. If a derived class does not redefine a virtual, then the version it uses is the one defined in its base class. A derived type must include a declaration for each inherited member it intends to redefine.
29、 Our Bulk_item class says that it will redefine the net_price function but will use the inherited version of book. Public, Private, and Protected InheritanceAccess to members defined within a derived class is controlled in exactly the same way as access is handled for any other class (Section 12.1.2
30、, p. 432). A derived class may define zero or more access labels that specify the access level of the members following that label. Access to the members the class inherits is controlled by a combination of the access level of the member in the base class and the access label used in the derived cla
31、ss derivation list.The base class itself specifies the minimal access control for its own members. If a member is private in the base class, then only the base class and its friends may access that member. The derived class has no access to the private members of its base class, nor can it make thos
32、e members accessible to its own users. If a base class member is public or protected, then the access label used in the derivation list determines the access level of that member in the derived class: In public inheritance, the members of the base retain their access levels: The public members of th
33、e base are public members of the derived and the protected members of the base are protected in the derived. In protected inheritance, the public and protected members of the base class are protected members in the derived class. In private inheritance, all the members of the base class are private
34、in the derived class.As an example, consider the following hierarchy:class Base public:void basemem(); / public memberprotected:int i; / protected member/ .;struct Public_derived : public Base int use_base() return i; / ok: derived classes can access i/ .;struct Private_derived : private Base int us
35、e_base() return i; / ok: derived classes can access i;All classes that inherit from Base have the same access to the members in Base, regardless of the access label in their derivation lists. The derivation access label controls the access that users of the derived class have to the members inherite
36、d from Base: Base b;Public_derived d1;Private_derived d2;b.basemem(); / ok: basemem is publicd1.basemem(); / ok: basemem is public in the derived classd2.basemem(); / error: basemem is private in the derived classBoth Public_derived and Private_derived inherit the basemem function. That member retai
37、ns its access level when the inheritance is public, so d1 can call basemem. In Private_derived, the members of Base are private; users of Private_derived may not call basemem. The derivation access label also controls access from indirectly derived classes: struct Derived_from Private : public Priva
38、te_derived / error: Base:i is private in Private_derivedint use_base() return i; ;struct Derived_from_Public : public Public_derived / ok: Base:i remains protected in Public_derivedint use_base() return i; ;Classes derived from Public_derived may access i from the Base class because that member rema
39、ins a protected member in Public_derived. Classes derived from Private_derived have no such access. To them all the members that Private_base inherited from Base are private.Interface versus Implementation InheritanceA publicly derived class inherits the interface of its base class; it has the same
40、interface as its base class. In well-designed class hierarchies, objects of a publicly derived class can be used wherever an object of the base class is expected. Classes derived using either private or protected do not inherit the base-class interface. Instead, these derivations are often referred
41、to as implementation inheritance. The derived class uses the inherited class in its implementation but does not expose the fact of the inheritance as part of its interface. As well see in before, whether a class uses interface or implementation inheritance has important implications for users of the
42、 derived class.Constructors and Copy ControlThe fact that each derived object consists of the (nonstatic) members defined in the derived class plus one or more base-class subobjects affects how derived-type objects are constructed, copied, assigned, and destroyed. When we construct, copy, assign, or
43、 destroy an object of derived type, we also construct, copy, assign, or destroy those base-class subobjects. Constructors and the copy-control members are not inherited; each class defines its own constructor(s) and copy-control members. As is the case for any class, synthesized versions of the defa
44、ult constructor and the copy-control members will be used if the class does not define its own versions. Base-Class Constructors and Copy ControlConstructors and copy control for base classes that are not themselves a derived class are largely unaffected by inheritance. Our Item_base constructor loo
45、ks like many weve seen before: Item_base(const std:string This constructor uses the constructor initializer list to initialize its min_qty and discount members. The constructor initializer also implicitly invokes the Item_base default constructor to initialize its base-class part. The effect of runn
46、ing this constructor is that first the Item_base part is initialized using the Item_base default constructor. That constructor sets isbn to the empty string and price to zero. After the Item_base constructor finishes, the members of the Bulk_item part are initialized, and the (empty) body of the con
47、structor is executed. Passing Arguments to a Base-Class ConstructorIn addition to the default constructor, our Item_base class lets users initialize the isbn and price members. Wed like to support the same initialization for Bulk_item objects. In fact, wed like our users to be able to specify values
48、 for the entire Bulk_item, including the discount rate and quantity. The constructor initializer list for a derived-class constructor may initialize only the members of the derived class; it may not directly initialize its inherited members. Instead, a derived constructor indirectly initializes the
49、members it inherits by including its base class in its constructor initializer list: class Bulk_item : public Item_base public:Bulk_item(const std:stringThis constructor uses the two-parameter Item_base constructor to initialize its base subobject. It passes its own book and sales_price arguments to that constructor. We might use this constructor as follows: / arguments are the isbn, price, minimum quantity, and discountBulk_item bulk(“0-201-82470-1“, 50, 5, .19);bulk is built by first running