⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch05.htm

📁 c++语言操作手册
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  capsules that separate implementation from interface. C++ provides the necessary   mechanisms for data abstraction in the form of classes, which bundle data with   a full set of associated operations. Information hiding is achieved by means   of the <tt>private</tt> access specifier, which restricts the access to data   members to class members exclusively.</p><h4> Operator Overloading</h4><p>In object-based languages, the user can extend the definition of a built-in   operator to support a user-defined type (operator overloading is discussed in   Chapter 3, "Operator Overloading"). This feature provides a higher level of   abstraction by rendering user-defined types a status of built-in types. For   example</p><pre><tt>class Date</tt><tt>{</tt><tt>private:</tt><tt>  char day;</tt><tt>  char month;</tt><tt>  short year;</tt><tt>  long secs;</tt><tt>public:</tt><tt>  bool operator &lt; (const Date&amp; other);</tt><tt>  bool operator == (const Date&amp; other);</tt><tt>  //...other member functions</tt><tt>};</tt></pre><h4> Characteristics of Object-Based Programming</h4><p>In a way, object-based programming can be thought of as a subset of object-oriented   programming; that is, some common principles are adhered to in both paradigms.   Unlike object-oriented programming, however, object-based programming does not   use inheritance. Rather, each user-defined class is a self-contained entity   that is neither derived from a more general type, nor does it serve as a base   for other types. The lack of inheritance in this paradigm is not coincidental.   Proponents of object-based programming claim that inheritance complicates design,   and that it might propagate bugs and deficiencies in a base class to its subclasses.   Furthermore, inheritance also implies polymorphism, which is a source for additional   design complexities. For instance, a function that takes a base object as an   argument also knows how to handle any object that is publicly derived from that   base.</p><h4> Advantages of Object-Based Programming</h4><p>Object-based programming overcomes most of the shortcomings of procedural programming.   It localizes changes, it decouples implementation details from the interface,   and it supports user-defined types. The Standard Library provides a rich set   of abstract data types, including <tt>string</tt>, <tt>complex</tt>, and <tt>vector</tt>.   These classes are designed to provide an abstraction for very specific uses,   for example, character manipulations and complex numbers arithmetic. They are   not derived from a more general base class, and they are not meant to be used   as a base for other classes.</p><blockquote>  <hr>  <b>Abstract Data Types Versus Abstract Classes</b><br>  The terms <i>abstract data type</i> and <i>abstract class </i>refer to two entirely   different concepts, although both of them use the word <i>abstract</i> due to   a historical accident. An abstract data type (also called a <i>concrete type</i>)   is a self-contained, user-defined type that bundles data with a set of related   operations. It behaves in the same way as does a built-in type. However, it   is not extensible nor does it exhibit dynamic polymorphism. In contrast, an   abstract class is anything but an abstract data type. It is not a data type   (normally, abstract classes do not contain any data members), nor can you instantiate   an object thereof. An abstract class is merely a skeletal interface, that specifies   a set of services or operations that other (nonabstract) classes implement.   Unfortunately, the distinction between the two concepts is often confused. Many   people erroneously use the term <i>abstract data type</i> when they are actually   referring to an abstract class.   <hr></blockquote><h4> Limitations of Object-Based Programming</h4><p>Object-based programming is advantageous for specific uses. However, it cannot   capture real-world relationships that exist among objects. The commonality that   exists among a floppy disk and a hard disk, for instance, cannot be expressed   directly in an object-based design. A hard disk and a floppy disk can both store   files; they can contain directories and subdirectories, and so on. However,   the implementer has to create two distinct and autonomous entities in this case,   without sharing any common features that the two have.</p><h3> <a name="Heading5">Object-Oriented Programming</a></h3><p>Object-oriented programming overcomes the limitations of object-based programming   by providing the necessary constructs for defining <i>class hierarchies</i>.   A class hierarchy captures the commonality among similar -- and yet distinct   -- types. For example, the classes <tt>Mouse</tt> and a <tt>Joystick</tt> are   two distinct entities, yet they share many common features that can be factored   out into a common class, <tt>PointingDevice,</tt> which serves as a base class   for both. Object-oriented programming is based on the foundations of object-based   programming such as information hiding, abstract data typing, and encapsulation.   In addition, it supports inheritance, polymorphism, and dynamic<i> </i>binding.</p><h4> Characteristics of Object-Oriented Programming</h4><p>Object-oriented programming languages differ from one another, sometimes considerably.   Smalltalk programmers who migrate to C++, for instance, find the differences   between the two languages somewhat daunting. The same can be said, of course,   for C++ programmers who migrate to Smalltalk or Eiffel. However, several common   characteristics that exist in all object-oriented programming languages distinguish   them from non-object-oriented ones. These characteristics are presented in the   following sections.</p><p><b>Inheritance</b></p><p>Inheritance enables a derived class to <i>reuse</i> the functionality and interface   of its base class. The advantages of reuse are enormous: faster development   time, easier maintenance, and simpler extensibility. The designer of class hierarchies   captures the generalizations and commonality that exist among related classes.   The more general operations are located in classes that appear higher in the   derivation graph. Often, the design considerations are application-specific.   For instance, the classes <tt>Thesaurus</tt> and <tt>Dictionary</tt> might be   treated differently in an online ordering system of a bookstore and a computerized   library of the linguistics department in some university. In the bookstore's   online ordering system, the classes <tt>Thesaurus</tt> and <tt>Dictionary</tt>   can inherit from a common base class called <tt>Item:</tt></p><pre><tt>#include &lt;string&gt;</tt><tt>#include &lt;list&gt;</tt><tt>using namespace std;</tt><tt>class Review{/*...*/};</tt><tt>class Book</tt><tt>{</tt><tt>private:</tt><tt>  string author;</tt><tt>  string publisher;</tt><tt>  string ISBN;</tt><tt>  float list_price;</tt><tt>  list&lt;Review&gt; readers_reviews;</tt><tt>public:</tt><tt>  Book();</tt><tt>  const string&amp; getAuthor() const;</tt><tt>  //...</tt><tt>};</tt></pre><p>Classes <tt>Dictionary</tt> and <tt>Thesaurus</tt> are defined as follows:</p><pre><tt>class Dictionary : public Book</tt><tt>{</tt><tt>private:</tt><tt> int languages; //bilingual, trilingual etc.</tt><tt> //...</tt><tt>};</tt><tt>class Thesaurus: public Book</tt><tt>{</tt><tt>private:</tt><tt> int no_of_entries;</tt><tt>//...</tt><tt>};</tt></pre><p>However, the computerized library of the linguistics department might use a   different hierarchy:</p><pre><tt>class Library_item</tt><tt>{</tt><tt>private:</tt><tt>  string Dewey_classification; </tt><tt>  int copies;</tt><tt>  bool in_store;</tt><tt>  bool can_be_borrowed;</tt><tt>  string author;</tt><tt>  string publisher;</tt><tt>  string ISBN;</tt><tt>public:</tt><tt>  Library_item();</tt><tt>  const string&amp; getDewey_classification() const;</tt><tt>  //...</tt><tt>};</tt><tt>class Dictionary : public Library_item</tt><tt>{</tt><tt>private:</tt><tt> int languages;</tt><tt> bool phonetic_transciption;</tt><tt> //...</tt><tt>};</tt><tt>class Thesaurus: public Library_item</tt><tt>{</tt><tt>private:</tt><tt> int entries;</tt><tt> int century; //historical period of the language, e.g., Shakespeare's era</tt><tt>//...</tt><tt>};</tt></pre><p>These two hierarchies look different because they serve different purposes.   However, the crucial point is that the common functionality and data are "elevated"   to the base class that is extended by more specialized classes. Introducing   a new class, for example <tt>Encyclopedia</tt>, to either the bookstore ordering   system or the computerized library of the linguistics department is much easier   in an object-oriented environment. That is because most of the functionality   of the new class already exists in the base class, whatever it might be. On   the other hand, in an object-based environment, every new class has to be written   from scratch.</p><p><b>Polymorphism</b></p><p><i>Polymorphism</i> is the capability of different objects to react in an individual   manner to the same message. Polymorphism is widely used in natural languages.   Consider the verb <i>to close</i>: It means different things when applied to   different objects. Closing a door, closing a bank account, or closing a program's   window are all different actions; their exact meaning depends on the object   on which the action is performed. Similarly, polymorphism in object-oriented   programming means that the interpretation of a message depends on its object.   C++ has three mechanisms of static (compile-time) polymorphism: operator overloading,   templates, and function overloading. </p><p><b>Operator Overloading</b></p><p>Applying operator <tt>+=</tt>, for example, to an <tt>int</tt> or a <tt>string</tt>   is interpreted by each of these objects in an individual manner. Intuitively,   however, you can predict what results will be, and you can find some similarities   between the two. Object-based programming languages that support operator overloading   are, in a limited way, polymorphic as well.</p><p><b>Templates</b></p><p>A <tt>vector&lt;int&gt;</tt> and a <tt>vector&lt;string&gt;</tt> react differently;   that is, they execute a different set of instructions when they receive the   same message. However, you can expect similar behavior (templates are discussed   in detail in Chapter 9, "Templates"). Consider the following example:</p><pre><tt>vector &lt; int &gt; vi;  vector &lt; string &gt; names;</tt><tt>string name("Bjarne");</tt><tt>vi.push_back( 5 ); // add an integer at the end of the vector</tt><tt>names.push_back (name); //add a string at the end of the vector</tt></pre><p><b>Function Overloading</b></p><p>Function overloading is a third form of polymorphism. In order to overload   a function, a different list of parameters is used for each overloaded version.   For example, a set of valid overloaded versions of a function named <tt>f()</tt>   might look similar to the following:</p><pre><tt>void f(char c, int i);</tt><tt>void f(int i, char c); //order of parameters is significant</tt><tt>void f(string &amp; s);</tt><tt>void f();</tt><tt>void f(int i);</tt><tt>void f(char c);</tt></pre><p>Note, however, that a function that differs only by its returned type is illegal   in C++:</p><pre><tt>int f();  //error; differs from void f(); above only by return type</tt><tt>int f(float f);  //fine - unique signature</tt></pre><p><b>Dynamic Binding</b></p><p><i>Dynamic</i> <i>binding</i> takes the notion of polymorphism one step further.   In dynamic binding, the meaning of a message depends on the object that receives   it; yet, the exact type of the object can be determined only at runtime. Virtual   member functions are a good example of this. The specific version of a virtual   function might not be known at compile time. In this case, the call resolution   is delayed to runtime, as in the following example:</p><pre><tt>#include &lt;iostream&gt;</tt><tt>using namespace std;</tt><tt>class base</tt><tt>{</tt><tt>  public: virtual void f() { cout&lt;&lt; "base"&lt;&lt;endl;}</tt><tt>};</tt><tt>class derived : public base</tt><tt>{</tt><tt>  public: void f() { cout&lt;&lt; "derived"&lt;&lt;endl;} //overrides base::f</tt><tt>};</tt><tt>void identify(base &amp; b) // the argument can be an instance</tt><tt>                        // of base or any object derived from it</tt><tt>{</tt><tt>  b.f(); //base::f or derived::f? resolution is delayed to runtime</tt><tt>}</tt><tt>//a separate translation unit</tt><tt>int main()</tt><tt>{</tt><tt>  derived d;</tt><tt>  identify; // argument is an object derived from base</tt>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -