C++ core 2000

1,188 94 0
  • Loading ...
1/1,188 trang
Tải xuống

Thông tin tài liệu

Ngày đăng: 25/03/2019, 17:10

file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Core C++ A Software Engineering Approach Victor Shtern Publisher: Prentice Hall PTR First Edition July 24, 2000 ISBN: 0-13-085729-7, 1280 pages Master C++ the right way: From the software engineering perspective! Front Matter Table of Contents About the Author Master C++ the right way! Object-oriented approach to coding throughout ● Harness C++’s strengths; avoid its dangers ● Build more easily maintainable code Build more powerful, robust, maintainable C++ software! For developers with experience in any language, Victor Shtern’s Core C++ teaches C++ the right way: by applying the best software engineering practices and methodologies to programming in C++ Even if you’ve already worked with C++, this comprehensive book will show you how to build code that is more robust, far easier to maintain and modify, and far more valuable Shtern’s book teaches object-oriented principles before teaching the language, helping you derive all the power of object-oriented development to build superior software Learn how to make design decisions based on key criteria such as information hiding and pushing responsibilities from clients down to server classes Then, master every key feature of ANSI/ISO C++ from a software engineer’s perspective: classes, methods, const modifiers, dynamic memory management, class composition, inheritance, polymorphism, I/O, and much more If you want to build outstanding C++ software, coding skill isn’t enough Objects aren’t enough You must design, think, and program using today’s best software engineering practices and with Core C++, you will So, Core C++ delivers: ● ● The application of software engineering principles to C++ programming ● A strong emphasis on writing code for easier future maintainance and modification ● A practical understanding of object-oriented principles before teaching the language ● Insight into the latest ANSI/ISO C++ features ● Thorough explanations that respect your intelligence ● Hundreds of realistic, to-the-point code examples ● Levity Breaks: Stories and vignettes that illustrate key topics, concepts, and ideas through humor Every core series book: ● ● Demonstrates practical techniques used by professional developers file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1 of 1187) [8/17/2002 2:57:43 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm ● ● ● Features robust, thoroughly tested sample code and realistic examples Focuses on the cutting-edge technologies you need to master today Provides expert advice that will help you build superior software Table of Content Table of Content Preface How Is This Different from Other C++ Books? Who This Book Is For How This Book Is Organized Conventions Used in This Book Accessing the Source Code Feedback Acknowledgments Part I: Introduction to Programming with C++ Chapter Object-oriented approach: What's So Good About It? The Origins of the Software Crisis Remedy 1: Eliminating Programmers Remedy 2: Improved Management Techniques Remedy 3: Designing a Complex and Verbose Language The Object-Oriented Approach: Are We Getting Something for Nothing? Characteristics of the C++ Programming Language Summary Chapter Getting Started Quickly: A Brief Overview of C++ The Basic Program Structure Preprocessor Directives Comments Declarations and Definitions Statements and Expressions Functions and Function Calls Classes Dealing with Program Development Tools Summary Chapter Working with C++ Data and Expressions Values and Their Types file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (2 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Integral Types Floating Point Types Working with C++ Expressions Mixed Expressions: Hidden Dangers Summary Chapter C++ Control Flow Statements and Expressions Conditional Statements Iteration C++ Jump Statements Summary Chapter Aggregation with Programmer-Defined Data Types Arrays as Homogeneous Aggregates Structures as Heterogeneous Aggregates Unions, Enumerations, and Bit Fields Summary Chapter Memory Management: the Stack and the Heap Name Scope as a Tool for Cooperation Memory Management: Storage Classes Memory Management: Using Heap Input and Output with Disk Files Summary Part II: Object-oriented programing with C++ Chapter Programming With C++ Functions C++ Functions as Modularization Tools Argument Promotions and Conversions Parameter Passing in C++ Inline Functions Parameters with Default Values Function Name Overloading Summary Chapter Object-Oriented Programming with Functions Cohesion Coupling Data Encapsulation Information Hiding A Larger Example of Encapsulation file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (3 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Shortcomings of Encapsulation with Functions Summary Chapter C++ Class as a Unit of Modularization Basic Class Syntax Binding Together Data and Operations Elimination of Name Conflicts Implementing Member Functions Outside of Class Defining Class Objects of Different Storage Classes Controlling Access to Class Members Initialization of Object Instances Constructors as Member Functions Default Constructors Copy Constructors Conversion Constructors Destructors Timing of Constructor and Destructor Invocations Class Scope and the Overriding of Names in Nested Scopes Memory Management with Operators and Function Calls Using Returned Objects in Client Code More on the const Keyword Static Class Members Summary Chapter 10 Operator Functions: Another Good idea Overloading of Operators Limitations on Operator Overloading Overloaded Operators as Class Members Case Study: Rational Numbers Mixed Types as Parameters Friend Functions Summary Chapter 11 Constructors and Destructors: Potential Trouble More on Passing Objects by Value Operator Overloading for Nonnumeric Classes More on the Copy Constructor Overloading the Assignment Operator Practical Considerations: What to Implement Summary file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (4 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Part III: Object-Oriented Programming with Aggregation and Inheritance Chapter 12 Composite Classes: Pitfalls and Advantages Using Class Objects as Data Members Initialization of Composite Objects Data Members with Special Properties Container Classes Summary Chapter 13 Similar Classes: How to Treat Them Treating Similar Classes Syntax of C++ Inheritance Accessing Base and Derived Class Services Accessing Base Components of a Derived Class Object Scope Rules and Name Resolution Under Inheritance Constructors and Destructors for Derived Classes Summary Chapter 14 Choosing between Inheritance and Composition Choosing a Technique for Code Reuse Unified Modeling Language Case Study: A Rental Store On Class Visibility and Division of Responsibilities Summary Part IV: Advanced uses of C++ Chapter 15 Virtual Functions and other Advanced Uses of Inheritance Conversions Between Nonrelated Classes Conversions Between Classes Related Through Inheritance Virtual Functions: Yet Another New Idea Multiple Inheritance: Several Base Classes Summary Chapter 16 Advanced Uses of Operator Overloading Operator Overloading: A Brief Overview Unary Operators Subscript and Function Call Operators Input/Output Operators Summary Chapter 17 Templates: Yet Another Design Tool A Simple Example of a Class Design Reuse Syntax of Template Class Definition file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (5 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Template Classes with Several Parameters Relations Between Instantiations of Template Classes Template Specializations Template Functions Summary Chapter 18 Programming with Exceptions A Simple Example of Exception Processing Syntax of C++ Exceptions Exceptions with Class Objects Type Cast Operators Summary Chapter 19 What We Have Learned C++ as a Traditional Programming Language C++ as a Modular Language C++ as an Object-Oriented Language C++ and Competition Summary Preface Congratulations! You have opened one of the most useful C++ books on the market! It will teach you the strengths and weaknesses of C++, and it will this better than any other book I have seen And I have seen a lot of C++ books How Is This Different from Other C++ Books? Of course, any author can claim that his or her book is one of the best on the market What sets this book apart is its software engineering and maintenance perspective on writing C++ code Very few C++ books (if any) that Why is the software engineering and maintenance approach important? The point is that C++ changed not only the way we write computer programs, it also changed the way we learn programming languages In the "good old days," you would spend a day or two looking at the basic syntax of the language, then you would try your hand at simple programming problems Then you would learn more-complex syntax and would tackle more-complex problems In a week or two (or in three or four weeks for a really complex language), you would have seen it "all" and could pose as an "expert." It's different with C++; a very large and very complex language Granted, it is a superset of C, and file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (6 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm you can learn to write simple C programs (and, hence, C++ programs) very quickly But things are different for complex programs If the programmer does not know C++ well, a complex C++ program will not be portable; its code will be difficult to reuse, and it will be difficult to maintain C++ is a great language¡Xit was created as a general-purpose engineering language, and its design is a clear success Today, C++ is a language of choice for business, engineering, and even real-time applications Significant effort was spent on the design of the language, to ensure that C++ programs provide great performance, that they support dynamic memory management, and that different parts of programs could be made relatively independent Yet in all three areas, things can potentially go wrong even with a syntactically correct and thoroughly tested C++ program: It can be slow¡Xmuch slower¡Xthan a comparable C program It can contain memory management errors that affect the program only when memory usage changes (e.g., another program is installed); these errors might crash the program or quietly produce incorrect results It can contain dependencies between different parts of the program so that the maintainer has a hard time understanding the intent of the designer; a poorly written C++ program can be harder to maintain and reuse than a non-object-oriented program How important is this? If you are writing a small program that will be used only for a short time, then execution speed, memory management, maintainability, and reusability may not be of great importance All that counts is your ability to quickly produce a solution If this solution is not satisfactory, you can cut your losses by throwing the program away and writing another one For this, any C++ book would (but hey, you can still buy this one and enjoy its informal style and original insights into the language and its usage) However, if you are working in a group, creating large applications that cannot be easily discarded and will be maintained for a long time, everything matters The software engineering and maintenance approach I am advancing in this book is very useful and quite unique Most books on the market not mention these issues at all (Just check their indexes and see for yourself.) When they do, they fail to spell out the techniques that can remedy a tough situation Another important characteristic of this book is its approach to the presentation of the material There are many books on the market that a good job enumerating the features of the language but a mediocre job teaching you how to use the language This is similar to learning a natural language If you read a French grammar book, will it enable you to speak French? I did not study French, but I did study English, and I know¡Xreading grammar books does not help to develop language fluency In this book, I will show you how to use and how not to use the language, especially from the point of view of reusability and future maintenance file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (7 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Another teaching issue is that C++ features are so intertwined that it is hard to present C++ in a linear fashion, from simple to more complex Many C++ authors not even try They say that these efforts "offend the intelligence of the reader." As a result, they might mention in Chapter a concept that is explained only in Chapter 8, leaving the reader intimidated and frustrated My approach to teaching C++ is different I introduce topics cyclically, first as a general overview and then again at a greater depth, with bells and whistles, and nowhere will your understanding depend on material in later chapters I developed my approach through years of teaching working software professionals At Boston University Metropolitan College, most of my students hold professional jobs and come to classes in the evening in search of professional growth I also taught numerous professional development seminars and on-site training courses I developed great empathy for the students and their struggle with language concepts and programming techniques, and I translated this experience into a wellthought-out sequence of topics, examples, counterexamples, and recommendations I think that my approach to teaching C++ is fairly unique, and you will benefit from it Who This Book Is For This book is written for professionals who are looking for a no-nonsense presentation of practical details combined with a deep understanding of C++ subtleties This book is written for you if you are looking for practical details of new technologies with a thorough discussion of their use It is written for you if you have experience in other languages and are moving to C++ If you are an experienced C++ programmer, you will find this book useful and sometimes an eye-opener If this is your first programming book (and this is perfectly all right if it is), you will be well rewarded for the effort spent on reading it How This Book Is Organized I decided not to follow other authors who give you a detailed tour of their books, explaining what is covered and where Unfamiliar terms, concepts and techniques will not make much sense to you now and will probably be quite boring This is why I put the summary of the book into its final chapter, Chapter 19, "What We Have Learned," and you can read it if you are interested It makes more sense there Instead, let me tell you what parts of the book might be of interest to you, depending on your background and experience file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (8 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm ϒΠ If you are experienced in C++, Parts and will be most useful to you with their coverage of C++ power and programming pitfalls If, in your initial study of C++, you were rushed to objects without building your muscle in procedural programming, memory management, and creating maintainable code, a review of Parts and will also be helpful (and interesting) ϒΠ If you are an experienced C programmer who wants to move on to C++, Parts 2, 3, and are written for you If you briefly review Part 1, you might find the discussion of C from the software engineering and maintenance perspective interesting ϒΠ If you a programmer with experience in high-level languages other than C, C++, or Java, you should probably start with Part ϒΠ If you are looking for an introduction to programming, you should skip Chapter 1, "Object-Oriented Approach: What's So Good About It?": It will be too abstract for you at this stage Study the other chapters of Part first, then go back to Chapter 1, and then continue with Parts 2, 3, and Conventions Used in This Book All the code presented in the numbered listings in this book has been thoroughly debugged and tested using several compilers, including Microsoft Visual C++, Borland, and GNU compilers This code can be run without any modifications The code snippets outside of the listings have also been debugged and tested They are runnable, but they require a harness to be run Throughout the book, the code listings and snippets are presented in a monospace font The same is true of C++ terms in the text of the book If, for example, I am discussing a C++ class whose name is "Account," I will write it as Account, the way it would be written in program code When I talk about private data members, I will use the regular font for the word "private" and the monospace font for the keyword private Icons denote statements that are particularly useful or need your special attention They are notes, tips, and alerts NOTE This icon flags information that deserves special attention, such as an interesting fact about the topic at hand or one that the reader may want to keep in mind while programming ALERT file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (9 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm This icon flags information that, while useful, may cause unexpected results or serious frustration TIP This icon flags particularly useful information that will save the reader time, highlight a valuable programming tip, or offer specific advice on increasing productivity Accessing the Source Code It is important to practice when you learn a language Studying C++ without practicing it is as effective as taking a driver education course without driving: You'll learn a lot of useful things about driving, but you will not be able to drive I strongly recommend that you experiment with the programs discussed in this book The source code for all the listings can be found at the following site: ftp://ftp.prenhall.com/pub/ptr/c++_programming.w-050/core_c++/ Feedback This book was thoroughly reviewed, carefully edited, and meticulously proofread Still, some errors might remain In my drive to produce a unique book, I might have made statements that are groundless, unjustified, or plain erroneous Or, they could be controversial and you might want to debate them Please not hesitate to contact me at the following e-mail address: shtern@bu.edu For each typo or error that is pointed out to me or for each valid point regarding a discussion in the book, I promise to mention the names of the first two people who so in the next edition of this book Acknowledgments Many people helped me to make this book a reality and I am grateful to all of them First, I would like to thank Bjarne Stroustroup for designing this wonderful and powerful programming language We owe it all to him Next, I would like to thank Timothy Budd, Tom Cargill, Jim Coplien, Cay Horstmann, Ivor Horton, Bertrand Meyer, Scott Meyers, and Stephen Prata They wrote programming books that have file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (10 of 1187) [8/17/2002 2:57:44 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm between different invocations of the same function Dynamic storage class gives control over allocation and deallocation of the variable to the programmer There are two dangers that the programmer should avoid when the program uses dynamic memory management: not returning the memory that the program has and using the memory that the program does not have Not returning memory that the program has results in memory leak Memory leaks deplete the program of memory, especially when the program works around the clock The program crashes or produces incorrect results Using memory that the program does not have results in memory corruption The program crashes or produces incorrect results or produces correct results until the memory use on the computer changes The program suddenly crashes or produces incorrect results (quietly) C++ as an Object-Oriented Language Even without its object-oriented features, C++ provides a number of improvements over C Such features as end-of-line comments, flexible definitions of variables in the middle of a scope, symbolic constants for variables and pointers, the scope operator, function-like casts between types, the new and delete operators, default parameters, reference parameters, function and operator overloading, inline functions, the iostream library of I/O objects, and operations (this is quite a long list) contribute to the program quality But the major contribution of C++ to software engineering is the implementation of object-oriented features¡Xclasses, data members and member functions, constructors and destructors, class composition and inheritance, virtual functions, templates, and exceptions C++ Classes The major goal of C++ classes is to give the programmer the tool for binding together related data and operations This eliminates the drawbacks of using stand-alone global functions for implementing operations over values of programmer-defined data types The data is specified as class data members The operations are specified as class member functions The syntax of the class definition specifies data members and member functions within the class scope that is delimited by the opening and closing braces (followed by a semicolon) C++ allows the class designer to specify the rights that other parts of the program (client code) have for accessing the class components Public members can be referenced from everywhere where a class object can be defined Protected members can be referenced from class member functions and from member functions of the classes for which this class is a base class (directly or indirectly) file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1174 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Private members can be referenced from class member functions only Hence, parts of the program that not belong to the given class can access class public members only This rule can be relaxed with the use of friend classes and functions: They have the same access rights as the class member functions Usually, data members are defined as private, and member functions are defined as public This not only binds together data and operations in the eyes of the maintenance programmer, but it also hides data implementation from the client code With data private and operations public, the class is viewed by the client code as the combination of its function interfaces This supports such modern programming concepts as data encapsulation and information hiding Programming with data encapsulation prevents the client code from using the names of class private (or protected) data members This in turn protects the client code from ripple effects when the data implementation changes The client code is also protected from ripple effects of changes in the member function implementation as long as the function interfaces remain the same Of course, the benefits of object-oriented programming not come automatically just because C++ classes are used If member functions just save the values of class data members and retrieve them for use in the client code, the use of these functions in the client code does not make the client code easier to read or to modify The class designer has to push responsibility down to the server class instead of popping it up to the client code This is done by adding to class member functions that implement operations significant to achieving client code goals Expressing the client code in terms of calls to these server class member functions (rather then in terms of retrieving and manipulating class data members) makes class code self-explanatory, facilitates both design and maintenance, decreases the number of errors, and does all kinds of good things to the quality of the program Constructors, Destructors, and Overloaded Operators Constructors and destructors are special member functions that cannot have arbitrary programmerdefined names Their names must be derived from the name of the class to which they belong In return, the client programmer is freed from the duty of calling this function explicitly Instead, they are called automatically at specific moments in the life of a class object A constructor is automatically called immediately after a new class object is created (on the stack or on the heap) A class can have several constructors: They all have the same name (class name), but they should have different parameter lists Which constructor is called depends on the number and type of arguments that the client code specifies when the object is created In the constructor, the class designer specifies how the class data members are initialized and how file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1175 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm additional resources (e.g., heap memory) should be allocated Constructors should not have return types, and they cannot return values If the constructor should communicate with the caller and provide information that something went wrong when the object was initialized, the constructor could throw an exception Important constructors include a default constructor, a copy constructor, and conversion constructors The default constructor is called when an object is created without passing any arguments to it A conversion constructor is called when only one parameter (usually of the type of one of the class data members) is specified The copy constructor is called when another object of the same class is used to supply initialization data to the target object It is also called when a class object is passed to a function by value When the class objects allocate heap memory (or other resources) dynamically, passing these objects by value creates integrity problems: The program crashes or behaves erratically (or produces correct results until the memory usage of the computer changes) To prevent integrity problems, the copy constructor can be used to implement value semantics However, this slows the program down It is better to pass class objects by reference, not by value To make passing class objects by value impossible, the copy constructor can be declared private (or protected) A destructor is called automatically, immediately before the object is destroyed (because of the scope rules or as a result of the delete operator) In the destructor, the class designer specifies how the resources that the object acquired during its lifetime are returned to the system Destructors cannot have return types, they cannot return values; in addition, they cannot have parameters This means that the destructors cannot be overloaded Using constructors and destructors requires an adjustment in how we think about program execution In C++ (unlike in other languages) there is no such thing as merely creating or destroying an object of a programmer-defined type It is always a constructor call that follows the object creation, and it is always the destructor call that precedes the object destruction The usefulness of constructors and destructors for dynamic memory management cannot be overestimated Instead of dealing with complex and confusing linked data structures that consist of many diverse components, the programmer manages a narrow and well-defined task of handling only one or two components As a result, the complexity of the programmer's task decreases, and the likelihood of errors becomes less C++ is designed to treat objects of programmer-defined types and the variables of built-in types in the same way This is why, in addition to function overloading, C++ supports operator overloading This unique feature allows the client code to apply C++ operators to class objects In most cases, file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1176 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm this is a cosmetic, but nice, improvement Some overloaded operators provide more than just cosmetic improvement For example, the subscript operator can be designed to enforce index checking and avoid memory corruption that is a common threat when standard C++ arrays are used The assignment operator can be designed to enforce value semantics and avoid memory corruption and memory leaks If the value semantic is not necessary (one object should not be assigned from another object), the assignment operator should be made private (or protected) Class Composition and Inheritance Using classes gives the greatest flexibility when class objects work together C++ supports implementation of associations among objects using pointers and references: Data members of one class point to objects of another type C++ also supports class composition where objects of one class are used as data members of another class Another important relationship between classes that can be implemented in C++ is class inheritance, where one class is used as a base class and another class is used as a class derived from the base class With class composition, C++ breaks the process of object creation at run time into stages: First the component objects are created, and then the container object is created Since object creation is always accompanied by a function call to a constructor, creation of composite objects often becomes a long series of function calls that might affect program performance Another possible complication is that creating an object results in constructor calls to constructors that are not implemented by the class (resulting in a syntax error) C++ provides the initialization list technique that resolves both of these problems Its syntax is unusual (it gives yet another job to the colon operator), but the result is superior to the simpleminded approach It specifies the names of data members whose nondefault constructors should be called instead of default constructors and specifies the arguments for these constructor calls It is important to master this technique of object initialization and use it well With inheritance, C++ allows the programmer to link two classes with a conceptual link As a result, everything that is defined for the base class also becomes defined for the derived class The derived class can define some additional data members and member functions and also redefine some member functions, using the same name and replacing the function body with more appropriate contents From the client code point of view, an object of the derived class is the combination of capabilities defined in the base class and in the derived class Using inheritance is a great way to reuse software design, because the capabilities defined in the base class are immediately reused in the derived file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1177 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm class without writing any code As the result, a derived class object's data members are defined in the base class and in the derived class It also has member functions defined in the base class and in the derived class The client code has access to all public members (data members and member functions) of the derived class object, both inherited from the base class and added in the derived class The derived class code has access to public and protected members of the base class (both data members and member functions) but not to private base class members The syntax of inheritance reuses the keywords public, protected, private (and the colon operator) with different meaning With the public mode of inheritance, the public, protected, and private data members and member functions defined in the base class remain public, protected, and private in the derived class object With protected inheritance, public base members become protected in the derived class object and hence are not available to the client code With private inheritance, public and protected base members become private in the derived class object and hence are not available for further derivation This is a rather complex system of changing access rights, and it is a good idea to use public inheritance that maintains the most natural relationships between classes: An object of the derived class is also an object of the base class This means that a derived class object has all the data members and member functions of the derived class When an object of the derived class is instantiated, its base part is created first This involves a call to the base class constructor; the absence of the default constructor could present syntactic problems C++ provides the initialization list technique that resolves this problem Its syntax is similar to the initialization list for class composition, but the base class name is used instead of the names of the component data members It is important to master this technique of object initialization and use it well When a message is sent to an object of the derived class, the compiler searches the definition of the derived class for a match If no match is found, the compiler searches the base class (or the base of the base class, etc.); if a match is found there, the appropriate function call to the base method is generated; if no match is found, it is a syntax error If the function name is found in the derived class, the search is terminated If the arguments match the parameter list, the function call to a derived class method is generated If the arguments not match, the search is not resumed: It is a syntax error even when the base class has a function with the same name that matches the arguments This means that the derived class method hides the base class method of the same name, no matter what the signatures of these two methods are: There is no function overloading between functions in different scopes with different signatures This is often a source of subtle errors, when a function file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1178 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm that is actually called is different from the function the client programmer (or the maintainer) thinks should be called Since an object of the publicly derived class has all the properties of a base class object, the derived object can be used anywhere a base class object is expected¡Xin assignment, parameter passing, and pointer manipulation The conversion from derived objects (pointers, references) to base objects (pointers, references) is safe It can always be done and does not even need an explicit cast The conversion from a base object to a derived object is not safe It can be performed only if an explicit assignment operator or conversion constructor is available The conversion from a base class pointer (reference) to a derived class pointer (reference) is not safe It cannot be done implicitly: An attempt to so is flagged as a syntax error If the base pointer points to a derived class object, the conversion to the derived class pointer makes sense To talk the compiler into accepting such a conversion, the explicit cast should be used If the programmer makes a mistake (the base pointer does not point to a derived class object) a run-time error results Virtual Functions and Abstract Classes Virtual functions extend the concept of hiding base functions in derived class objects These functions are used when the program has to process a heterogeneous collection of objects that belong to a family of similar classes Each class defines a function (they use the same name, e.g., update; and the same signature) that performs a similar operation (again, update) on objects of these classes but does it somewhat differently for objects of different classes (e.g., SavingsAccount and CheckingAccount) The goal of the design is to achieve a polymorphic effect, that is, send the update() message to each object in the list and invoke either the update() message of the SavingsAccount class or the update() message of the CheckingAccount class To achieve that goal, you derive these similar classes from the same class (e.g., Account) There are several restrictions to abide by The derivation should be public The base class should have the method with the same name and the same signature (e.g., update) as in the derived classes This method should be defined as virtual The heterogeneous collection of objects should be implemented as a list of pointers of the base class pointing to dynamically allocated objects of derived classes As the reward for complying with these limitations, the message sent to the base pointer does not invoke the base class method, but rather invokes the method of the derived class to which the object file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1179 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm pointed to by the pointer belongs For example, if the base pointer points to a SavingsAccount object, it will call the update() method from the SavingsAccount class If it points to a CheckingAccount object, it will call the update() method of the CheckingAccount class Many C++ programmers are excited about this technique This is small wonder because this technique is very nice and very elegant However, it is not terribly important because the processing of heterogeneous lists is not the most frequent programming task Often, the base objects for such a family of classes have no job in the application (e.g., the application deals with savings accounts and checking accounts, but not with unidentified accounts) The further extension of this technique is making the base class into an abstract class In an abstract class, the virtual function is defined as a pure virtual function, that is, as a function that has no implementation Instead, its prototype in the class specification is "assigned" to zero This is the syntax that defines the virtual function as a pure function and the base class as an abstract class The application cannot create objects of the abstract class If the programmer creates an object of the abstract class by mistake, it will be flagged as a syntax error Templates Templates represent yet another tool for design reuse When the application needs container classes that contain components of different types, it would be nice to avoid repeating the design for each component type¡Xthese classes would be almost identical C++ templates allow the programmer to create a class where the type of components is defined as a class parameter When an object of this type is instantiated, the client code supplies the name of the actual type, and the compiler generates class object code where each instance of the class parameter is replaced by the name of the actual type specified by the client code The template syntax is rather complex: It involves using parameter lists in angle brackets The syntax of object instantiation is also complex: The client code specifies actual types also by using angle brackets Implementation of member functions requires angle brackets for the formal parameter lists and for the class name in the scope operator It is not clear to what extent individual applications can benefit from using templates This is a relatively new feature that is not supported by all compilers yet and the experience of using this feature is limited However, the C++ Standard Template Library uses templates to implement data structures such as lists, queues, vectors, hash tables, and the like These classes are well designed and optimized Their use in individual applications is definitely beneficial This is why it is important to understand the syntax of instantiating and using template objects file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1180 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Exceptions Exceptions also represent a new C++ feature, designed to support separation between the processing of the main algorithm and the processing of exceptional and rare cases Presumably, this untangles convoluted code, contributes to streamlining the main processing algorithm, and reduces the complexity of the entire program When exception is thrown, an object of a built-in or programmer-defined type is created and sent from the place where the exceptional condition occurred to the place where the exception should be processed This value (or object) carries the information that is useful for exception processing, for example, a string with an error message The syntax of using exceptions requires the programmer to write statements for claiming exceptions, throwing exceptions, and catching exceptions When claiming exceptions, the programmer uses the keyword throw between the function header and the function body followed by the list of types that this function could throw (in parentheses, comma separated) If the function prototype is specified, the keyword and the list are inserted between the closing parenthesis of the parameter list and the final semicolon When throwing an exception, the programmer uses the same keyword throw with the single argument (a value of a built-in type or an object of a programmer-defined type) This statement is usually used within a conditional: Some condition is tested, and if it turns out to be true, the exception is thrown to notify the exception handler that the condition turns out to be true If the throw statement throws an exception of a programmer-defined class, and the data should be passed with the object, the exception class should define a constructor that accepts necessary values and initializes object data members If the object does not need any data, the default constructor is called: Unlike in all other cases of creating an object with a default constructor, the empty parentheses must be used after the name of the object When catching an exception, a complex syntactic construct should be used¡Xthe try block with a statement that could throw an exception and the set of catch blocks that follow the try block Each catch block is designed to process an exception of only one type The try block is just an unnamed block that is preceded by the keyword try A catch block is just a block that is preceded by the keyword catch and a parameter list with only one parameter The type of the catch parameter is of the type (built-in or programmer defined) that this catch block is designed to process If the statements in the try block throw no exception, the try block terminates, the catch blocks are file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1181 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm skipped, and the next statement (if any) is executed If one of the statements in the try block throws an exception, the segment of code from this place until the end of the try block is skipped; it will not be executed even if the exception is caught and processed Then the catch blocks are examined in sequence for a match between the type in the parameter list and the type of the value thrown in the exception If the value does not match, the next catch block is examined If the value matches the parameter type, this catch block is executed and does whatever it takes to process this exception After that, the rest of the catch blocks are skipped, and the statement following the last catch block is executed If no match is found, the statements following the try-catch sequence are skipped, and the function that contains this try-catch sequence is terminated Before termination, it throws the exception that has not been caught, and the search continues in the caller of this function If the catch block that handles the exception is found, all is well and the program continues If not, the search propagates to main() and the program is terminated This technique can result in complex coding patterns because the programmer can place the trycatch sequences in any function and in any combination Often, it is hard to figure out in what place the exception is processed and how the program continues the execution It is not clear whether the use of exceptions indeed results in streamlining of the main line of processing and in easy-tounderstand exception processing The advantage of this technique is that the place of error discovery can be quite separated from the place of error recovery, and all the necessary information can be sent from the place of discovery to the place of recovery inside the exception object thrown by the throw statement Another advantage is that the destructors are called for all the objects that are removed from the stack in the process of terminating the functions that not have the appropriate catch block This means that if the program recovers from the error and continues execution, it will not suffer from the memory leak C++ and Competition In a sense, C++ competes with every programming language in use today, from FORTRAN and COBOL to PL/I and Ada C++ and Older Languages Of course, even older languages have their own strengths For example, FORTRAN is superior for implementing scientific algorithms Its libraries make the job of a scientific programmer much easier COBOL and PL/I are superior to C++ when it comes to flexible formatting of output: a C++ programmer has to work much harder to achieve similar results, especially if the iostream library is file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1182 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm used If the older standard library is used, formatting code can be more concise Still, it is error prone and complicated Ada has such features as tasks for concurrent programming and packages for implementing simple objects These features allow the programmer to implement basic object-oriented designs However, none of these languages supports composition, inheritance, and virtual functions Objectoriented features of C++ make it superior to these languages for writing large applications C++ and Virtual Basic One interesting competitor to C++ that is becoming more and more important is Visual Basic Over the years, Visual Basic has evolved from a very simple language into a powerful and flexible language The output formatting facilities that Visual Basic supports rival those of COBOL and PL/I and are much better than those supported by C++ Visual Basic gives the programmer quick and easy access to building interactive input and output with Graphical User Interfaces (GUIs) For C++ programmer to achieve a similar effect, one has to learn a window library, and all libraries available on the market today are extremely difficult to learn and to use Visual Basic also supports some object-oriented features, even though its object-oriented features not rival those of C++ The learning curve for Visual Basic is easier than for C++: One can learn to produce meaningful applications in Visual Basic much faster than in C++ However, object-oriented features of C++ are integrated into the language better than in Visual Basic, where they remain a nice but alien addition C++ and C Another language with which C++ has to compete now is its own predecessor, the C programming language C remains a language of choice for those programmers who develop real-time and embedded systems These programmers are apprehensive of such complex C++ features as virtual functions, templates, iostream library, and exceptions They have a point¡Xall of these features affect program performance and increase the size of the executable code For real-time and embedded systems, both performance and the size of executables are of primary importance This is why acceptance of C++ for these kinds of applications has been relatively slow I think this was a mistake C is a language designed for quick and sharp minds, and it is conducive to using concise and expressive coding patterns These coding patterns sometimes become quite file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1183 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm confusing for the reader, especially when the programmer tries to optimize performance and minimize the size of the object code As a result, the organizations that use C for real-time and embedded systems wind up with complex schemes of using memory, complex global data structures with dynamic memory management, and convoluted calling conventions The design of these systems is so complex that they cannot be properly documented given the pressure of tight release schedules Training new hires takes a long time and negatively affects the productivity of existing staff Misconceptions and incomplete understanding of decisions made for other parts of the system lead to design errors and mistakes in maintenance that are costly to correct I am not sure whether what I am describing is universal, but this is what I saw in several companies that were struggling with the issue of switching from C to C++ It is obvious that using C++ classes with private data members and public member functions will result in better modularization of code with no effect on program performance and on the size of the object code Using constructors and destructors properly will eliminate mistakes in memory management and will make the search for errors easier Also, limited use of virtual functions will not have a significant impact on program size and performance After all, polymorphic algorithms can be implemented in any language, and when you implement them, say, in C, you allocate additional memory to store information about the kind of object the program is dealing with, and the program spends some time figuring out how to treat this object Using C++ encapsulates this complexity for the programmer and does not waste additional resources Unfortunately, many C++ compilers produce bloated object code regardless of whether the programmers use templates, iostream libraries, exceptions, or run-time identification The limited use of advanced C++ facilities requires cooperation from compiler vendors, so that the programmers could choose what should be included in each build I think that eventually all C programmers will switch to C++, even if not all C++ features will be used in each application C++ and Java Java is probably the most formidable competition to C++ today Java is a C++ cousin¡Xsimilar to C++, it was designed as a superset of C Most of Java object-oriented syntax is borrowed from C++ (with some changes) Similar to C++, Java was designed to support classes with data members, member functions, constructors, virtual functions, and exceptions Java code is a collection of cooperating objects that provide services to each other Java supports class composition, class inheritance, and polymorphism Java encourages reuse of programmer-defined classes and reuse of the library file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1184 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm classes for graphical visual user interface Unlike C++, the goal of backward compatibility with C was not a Java design goal As a result, Java avoided a significant number of error-prone features that C++ inherited from C In addition, Java does not include a number of C++ features that either result in the increase in size of object code or encourage inferior software engineering techniques Some people say that Java does not have pointers, and hence Java source code is much simpler that comparable C++ code These people just not know what they are talking about Java does have pointers; those who not believe me are invited to run a simple program and see the message "Null pointer exception" appear on the screen before the program aborts Java has an explicit new operator similar to C++ However, Java does not have an explicit delete operator Instead, Java uses garbage collection This is a major break from C/C++ ideology: Less time is spent on debugging of memory management; more time is left for other algorithms The use of the garbage collector, along with the use of the interpreter during run time, makes Java significantly slower than C++ A few years ago, this conclusion would have meant the death of the language: Nobody would touch it with a ten-foot pole Not so today Performance, however important, is not the most important criteria in evaluating a programming language anymore Portability, robustness, and simplicity are much more important (provided that the language does support a modern object-oriented software engineering approach) Java is portable: All Java data types are of standard sizes on all machines An integer is always four bytes; it is not necessarily the fastest type on a given platform, but the program executes the same way on all machines One cannot choose between signed and unsigned data types: Numeric types are always signed, and boolean and characters are always unsigned Java identifiers can be of any length Java is robust: Implicit casts between numeric types are not allowed; explicit casts are allowed between numeric types but not between numeric types and boolean types Unlike in C/C++, the relational and logical operators return boolean "true" or "false", and not int or 0; hence, misspelling the comparison operator == as an assignment operator = is flagged as a syntax error¡Xa major source of programming errors disappears without a trace Java is simple: It lacks many error-prone C++ features: overloading operator functions, generic templates, multiple inheritance, parameter passing by pointer, pointer-related unprotected array operations, friend classes and functions, global functions, and variables with project-wide names (Each Java function, including main, must be a member of some class.) Java has no preprocessor with its macros, include files, and conditional compilations There is no file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1185 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm need for function prototypes¡Xa major source of headache in C++ The Java compiler knows where libraries are located and does not expect the programmer to specify the location Java implements object-oriented features that C++ does not have: All functions are virtual functions by default, inheritance supports both hiding the base functions in the derived class and overloading if the signatures are different; classes can be combined into packages Java has the interface construct that governs the use of objects of one class where the object of another class is expected better than inheritance Java supports threads that help implement concurrency Instead of producing machine-dependent object code, the Java compiler generates so-called bytecode that requires the interpreter to be run This looks like a liability, right? No, this means that Java bytecode can run on any platform equipped with a Java interpreter: A program compiled on a Solaris machine can run on any UNIX, PC, or Mac machine without any changes C++ programmers cannot even dream about this kind of portability This is why Java is such a success as an Internet language: The bytecode produced on one platform can be downloaded from another platform and executed without even asking what the server platform is Java programs can be used on heterogeneous networks as easily as on homogeneous networks Java comes with a huge library of GUI classes It is true that learning these classes is no piece of cake However, a novice programmer can produce a meaningful Java application almost as easily as producing a Visual Basic application and much more easily and faster than producing a similar C++ application On the Internet, Java is a clear winner For backend processing, C++ is a clear winner, mostly because of its performance superiority But the situation today is not as clear cut as it was several years ago Summary How you like it? You have seen it all by now I have tried to be honest with you about the advantages and disadvantages of C++ Those features that are great, I told you are great Those features that are not so great, I told you are not so great Those features that are dangerous, I told you are dangerous But first and foremost, I tried to show you that using C++ effectively requires a change in programming thinking You should think about the division of responsibilities between different parts of a program and about pushing these responsibilities down to server classes You should think about making design decisions clear to the maintenance programmer in code, without comments You should think about using objects of one class where an object of another class is expected file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1186 of 1187) [8/17/2002 2:58:13 PM] file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm Using these software engineering principles, you will be able to create robust, portable, reusable, and maintainable C++ applications And you will be able to that while having fun, because C++ is a fun language to use I wish you well! file://///Administrator/General%20English%20Learning/it2002-7-6/core.htm (1187 of 1187) [8/17/2002 2:58:13 PM] InformIT Author Biography Victor Shtern Victor Shtern is Professor at Boston University's Metropolitan College, considered one of the top U.S schools for working professionals In addition to teaching C++ at the university level, Shtern also teaches training courses to experienced programmers Technical Reviewers: Dan Costello, Senior Software Engineer, GE Marquette Medical Systems Steve Glass, Senior Software Engineer, Motorola Technical Editor: Clovis Tondo, author of The C Answer Book and The C++ Answer Book Close Window http://www.informit.com/safari/author_bio.asp?ISBN=0130857297 [8/17/2002 3:42:32 PM] ... Object-oriented programing with C++ Chapter Programming With C++ Functions C++ Functions as Modularization Tools Argument Promotions and Conversions Parameter Passing in C++ Inline Functions Parameters... Syntax of C++ Exceptions Exceptions with Class Objects Type Cast Operators Summary Chapter 19 What We Have Learned C++ as a Traditional Programming Language C++ as a Modular Language C++ as an... file://///Administrator/General%20English%20Learning/it2002-7-6 /core. htm you can learn to write simple C programs (and, hence, C++ programs) very quickly But things are different for complex programs If the programmer does not know C++ well, a complex C++
- Xem thêm -

Xem thêm: C++ core 2000 , C++ core 2000 , Chapter 1. Object-oriented approach: What's So Good About It?, Chapter 2. Getting Started Quickly: A Brief Overview of C++, Chapter 3. Working with C++ Data and Expressions, Chapter 5. Aggregation with Programmer-Defined Data Types, Chapter 6. Memory Management: the Stack and the Heap, Chapter 7. Programming With C++ Functions, Chapter 8. Object-Oriented Programming with Functions, Chapter 9. C++ Class as a Unit of Modularization, Chapter 10. Operator Functions: Another Good idea, Chapter 11. Constructors and Destructors: Potential Trouble, Chapter 12. Composite Classes: Pitfalls and Advantages, Chapter 13. Similar Classes: How to Treat Them, Chapter 14. Choosing between Inheritance and Composition, Chapter 15. Virtual Functions and other Advanced Uses of Inheritance, Chapter 16. Advanced Uses of Operator Overloading, Chapter 17. Templates: Yet Another Design Tool, Chapter 19. What We Have Learned

Tài liệu mới bán

Gợi ý tài liệu liên quan cho bạn