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

📄 index.html

📁 C程序员手册(英文)
💻 HTML
📖 第 1 页 / 共 5 页
字号:
  <i>abstract data types</i> (not to be confused with <i>abstract classes</i>; 
  see the sidebar titled "Abstract Data Types Versus Abstract Classes" later in 
  this chapter). </p>
<p>These classes can meet a vast variety of needs in clean and easy-to-maintain 
  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>

⌨️ 快捷键说明

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