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

📄 index.html

📁 C程序员手册(英文)
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
	<META NAME="Author" Content="Steph Mineart">
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
	<TITLE>ANSI/ISO C++ Professional Programmer's Handbook - Chapter 5 - Object-Oriented Programming and Design</TITLE>
	<link rel="stylesheet"  TYPE="text/css" href="/includes/stylesheets/ebooks.css">
</head>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF">

<CENTER>
<H1><img src="/publishers/que/series/professional/0789720221/button/que.gif" WIDTH="171" HEIGHT="66" ALIGN="BOTTOM" BORDER="0"><BR>
ANSI/ISO C++ Professional Programmer's Handbook</H1>
</CENTER>
<CENTER>
  <P><A HREF="/publishers/que/series/professional/0789720221/index.htm"><img src="/publishers/que/series/professional/0789720221/button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> 
  <HR>
</CENTER>
<H1 align="center">5</H1>
<h1 align="center"> Object-Oriented Programming and Design</h1>
<address>by Danny Kalev </address>
<ul>
  <li><a href="#Heading1">Introduction</a> 
  <li><a href="#Heading2">Programming Paradigms</a> 
    <ul>
      <li><a href="#Heading3">Procedural Programming</a> 
      <li><a href="#Heading4">Object-Based Programming</a> 
      <li><a href="#Heading5">Object-Oriented Programming</a> 
    </ul>
  <li><a href="#Heading6">Techniques Of Object-Oriented Programming</a> 
    <ul>
      <li><a href="#Heading7">Class Design</a> 
      <li><a href="#Heading8">The "Resource Acquisition Is Initialization" Idiom</a> 
    </ul>
  <li><a href="#Heading9">Classes and Objects</a> 
  <li><a href="#Heading10">Designing Class Hierarchies</a> 
    <ul>
      <li><a href="#Heading11">Private Data Members Are Preferable To Protected 
        Ones</a> 
      <li><a href="#Heading12">Declaring Virtual Base Class Destructors</a> 
      <li><a href="#Heading13">Virtual Member Functions</a> 
      <li><a href="#Heading14">Abstract Classes and Interfaces</a> 
      <li><a href="#Heading15">Use Derivation Instead of Type-Fields</a> 
      <li><a href="#Heading16">Overloading A Member Function Across Class Boundaries</a> 
      <li><a href="#Heading17">Deciding Between Inheritance and Containment</a> 
      <li><a href="#Heading18">The Holds-a Relation</a> 
      <li><a href="#Heading19">Empty Classes</a> 
      <li><a href="#Heading20">Using structs as A Shorthand for Public Classes</a> 
      <li><a href="#Heading21">Friendship</a> 
      <li><a href="#Heading22">Nonpublic Inheritance</a> 
      <li><a href="#Heading23">Common Root Class</a> 
      <li><a href="#Heading24">Forward Declarations</a> 
      <li><a href="#Heading25">Local Classes</a> 
      <li><a href="#Heading26">Multiple Inheritance</a> 
    </ul>
  <li><a href="#Heading27">Conclusions</a> 
</ul>
<hr size=4>
<h2> <a name="Heading1">Introduction</a></h2>
<p>C++ is the most widely used object-oriented programming language today. The 
  success of C++ has been a prominent factor in making object-oriented design 
  and programming a de facto standard in today's software industry. Yet, unlike 
  other object-oriented programming languages (some of them have been around for 
  nearly 30 years), C++ does not enforce object-oriented programming -- it can 
  be used as a "better C", as an <i>object-based</i> language, or as a generic 
  programming language. This flexibility, which is unparalleled among programming 
  languages, makes C++ a suitable programming language in any domain area -- real 
  time, embedded systems, data processing, numerical computation, graphics, artificial 
  intelligence, or system programming.</p>
<p>This chapter begins with a brief survey of the various programming styles that 
  are supported by C++. Next, you will focus on various aspects of object-oriented 
  design and programming.</p>
<h2> <a name="Heading2">Programming Paradigms</a></h2>
<p>A programming paradigm defines the methodology of designing and implementing 
  software, including the building blocks of the language, the interaction between 
  data structures and the operations applied to them, program structure, and how 
  problems are generally analyzed and solved. A programming language provides 
  the linguistic means (keywords, preprocessor directives, program structure) 
  as well as the extra-linguistic capabilities, namely standard libraries and 
  programming environment, to support a specific programming paradigm. Usually, 
  a given programming language is targeted for a specific application domain, 
  for example, string manipulation, mathematical applications, simulations, Web 
  programming and so on. C++, however, is not confined to any specific application 
  domain. Rather, it supports many useful programming paradigms. Now, for a discussion 
  of some of the most prominent programming paradigms supported in C++.</p>
<h3> <a name="Heading3">Procedural Programming</a></h3>
<p>C++ is a superset of ISO C. As such, it can be used as a procedural programming 
  language, albeit with tighter type checking and several enhancements that improve 
  design and coding: reference variables, inline functions, default arguments, 
  and <tt>bool</tt> type. Procedural programming is based on separation between 
  functions and the data that they manipulate. In general, functions rely on the 
  physical representation of the data types that they manipulate. This dependency 
  is one of the most problematic aspects in the maintenance and extensibility 
  of procedural software.</p>
<h4> Procedural Programming Is Susceptible To Design Changes</h4>
<p>Whenever the definition of a type changes (as a result of porting the software 
  to a different platform, changes in the customer's requirement, and so on), 
  the functions that refer to that type have to be modified accordingly. The opposite 
  is also true: When a function is being changed, its arguments might be affected 
  as well; for instance, instead of passing a struct by value, it might be passed 
  by address to optimize performance. Consider the following:</p>
<pre>
<tt>struct Date //pack data in a compact struct</tt>
<tt>{</tt>
<tt>  char day;</tt>
<tt>  char month;</tt>
<tt>  short year;</tt>
<tt>};</tt>
<tt>bool isDateValid(Date d); //pass by value</tt>
<tt>void getCurrentDate(Date * pdate); //changes its argument, address needed</tt>
<tt>void initializeDate (Date* pdate); //changes its argument, address needed</tt>
</pre>
<p>Data structures, such as <tt>Date</tt>, and the group of associated functions 
  that initialize, read, and test it are very common in software projects in which 
  C is the predominant programming language. Now suppose that due to a change 
  in the design, <tt>Date</tt> is required to also hold the current time stamp 
  in seconds. Consequently, a change in the definition of <tt>Date</tt> is made:</p>
<pre>
<tt>struct Date</tt>
<tt>{</tt>
<tt>  char day;</tt>
<tt>  char month;</tt>
<tt>  short year;</tt>
<tt>  long seconds;</tt>
<tt>}; //now less compact than before</tt>
</pre>
<p>All the functions that manipulate <tt>Date</tt> have to be modified to cope 
  with change. An additional change in the design adds one more field to store 
  millionths of a second in order to make a unique timestamp for database transactions. 
  The modified <tt>Date</tt> is now</p>
<pre>
<tt>struct Date</tt>
<tt>{</tt>
<tt>  char day;</tt>
<tt>  char month;</tt>
<tt>  short year;</tt>
<tt>  long seconds;</tt>
<tt>  long millionths;</tt>
<tt>};</tt>
</pre>
<p>Once more, all the functions that manipulate <tt>Date</tt> have to be modified 
  to cope with the change. This time, even the interface of the functions changes 
  because <tt>Date</tt> now occupies at least 12 bytes. Functions that are passed 
  a <tt>Date</tt> by value are modified to accept a pointer to <tt>Date</tt>.</p>
<pre>
<tt>bool isDateValid(Date* pd); // pass by address for efficiency</tt>
</pre>
<h4> Drawbacks of Procedural Programming</h4>
<p>This example is not fictitious. Such frequent design changes occur in almost 
  every software project. The budget and time overhead that are produced as a 
  result can be overwhelming; indeed, they sometimes lead to the project's discontinuation. 
  The attempt to avoid -- or at least to minimize -- these overheads has led to 
  the emergence of new programming paradigms.</p>
<p>Procedural programming enables only a limited form of code reuse, that is, 
  by calling a function or using a common user-defined data structure. Nonetheless, 
  the tight coupling between a data structure and the functions that manipulate 
  it considerably narrows their reusability potential. A function that computes 
  the square root of a <tt>double</tt> cannot be applied to a user-defined <tt>struct</tt> 
  that represents a <tt>complex</tt>, for example. In general, procedural programming 
  languages rely on static type checking, which ensures better performance than 
  dynamic type checking -- but it also compromises the software's extensibility.</p>
<p>Procedural programming languages provide a closed set of built-in data types 
  that cannot be extended. User-defined types are either unsupported or they are 
  "second class citizens" in the language. The user cannot redefine built-in operators 
  to support them. Furthermore, the lack of abstraction and information hiding 
  mechanisms force users to expose the implementation details. Consider the standard 
  C functions <tt>atof()</tt>, <tt>atoi()</tt>, and <tt>atol()</tt>, which convert 
  a C-string to <tt>double</tt>, <tt>int</tt>, and <tt>long</tt>, respectively. 
  Not only do they force the user to pay attention to the physical data type of 
  the return value (on most machines these days, an <tt>int</tt> and a <tt>long</tt> 
  are identical anyway), they also prohibit the use of other data types.</p>
<h4> Why Procedural Programming Still Matters</h4>
<p>In spite of its noticeable drawbacks, procedural programming is still the preferred 
  programming paradigm in some specific application domains, such as embedded 
  and time critical systems. Procedural programming is also widely used in machine 
  generated code because code reuse, extensibility, and maintenance are immaterial 
  in this case. Many SQL interpreters, for example, translate the high-level SQL 
  statements into C code that is then compiled.</p>
<p>Procedural programming languages -- such as C, Pascal, or Fortran -- produce 
  the most efficient machine code among high-level programming languages. In fact, 
  development teams that are reluctant to adopt object orientation often point 
  to performance degradation as the major deterring factor.</p>
<p>The evolution of C++ is unique among programming languages. The job of its 
  creators might have been a lot easier had they chosen to design it from scratch, 
  without guaranteeing backward compatibility with C. Yet this backward compatibility 
  is one of the its strengths: It enables organizations and programmers to benefit 
  from C++ without having to trash hundreds of millions of lines of working C 
  code. Furthermore, C programmers can easily become productive in C++ even before 
  they have fully mastered object-oriented programming.</p>
<h3> <a name="Heading4">Object-Based Programming</a></h3>
<p>The limitations of procedural programming have led researchers and developers 
  alike to find better methods of separating implementation details from interfaces. 
  Object-based programming enables them to create user-defined types that behave 
  like first class citizens. User-defined types can bundle data and meaningful 
  operations in a single entity -- a <i>class</i>. Classes also support information 
  hiding, thereby separating implementation details such as physical representation 
  and underlying bookkeeping from the set of services that a class provides, or 
  its <i>interface</i>. Users of a class are allowed to access its interface, 
  but they cannot access its implementation details. The separation between the 
  implementation -- which might vary rather frequently due to design changes, 
  portability, and efficiency -- and the stable interface is substantial. This 
  separation ensures that changes in the design are localized to a single entity 
  -- the class implementation; the class users, on the other hand, are not affected. 
  To assess the importance of object-based programming, examine a simple minded 
  <tt>Date</tt> class:</p>
<pre>
<tt>class Date</tt>
<tt>{</tt>
<tt>private:</tt>
<tt>  char day;</tt>
<tt>  char month;</tt>
<tt>  short year;</tt>
<tt>public:</tt>
<tt>  bool isValid();</tt>
<tt>  Date getCurrent();</tt>
<tt>  void initialize();</tt>
<tt>};</tt>
</pre>
<h4> Object-Based Programming Localizes Changes In Implementation Details</h4>
<p>Now suppose that you have to change the definition of <tt>Date</tt> to support 
  time:</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 isValid();</tt>
<tt>  Date getCurrent();</tt>
<tt>  void initialize ();</tt>
<tt>};</tt>
</pre>
<p>The addition of a new data member does not affect the interface of <tt>Date</tt>. 
  The users of <tt>Date</tt> don't even know that a new field has been added; 
  they continue to receive the same services from the class as before. Of course, 
  the implementer of <tt>Date</tt> has to modify the code of the member functions 
  to reflect the change. Therefore, <tt>Date::initialize()</tt> has to initialize 
  one more field. Still, the change is localized only to the definition of <tt>Date::initialize()</tt> 
  because users cannot access the underlying representation of <tt>Date</tt>. 
  In procedural programming, however, users can access the data members of <tt>Date</tt> 
  directly.</p>
<h4> Abstract Data Types</h4>
<p>Classes such as <tt>Date</tt> are sometimes called <i>concrete types,</i> or 

⌨️ 快捷键说明

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