069 072


Common Sense C - Advice and Warnings for C and C++ Programmers:Working with C++






Common Sense C - Advice & Warnings for C and C++ Programmers

by Paul Conte

29th Street Press

ISBN: 1882419006   Pub Date: 10/01/92  




Previous Table of Contents Next Chapter 8Working with C++ Deck: Avoid “overloading” on object-oriented programming Why is C’s successor called “C plus-plus”? One rationale is that C++ is a “better C” (the first “plus”) and adds object-oriented programming (OOP) features (the second “plus”). But C++ brings with these beneficial additions some devilish problems. Maybe they should have called it “C plus-plus-plus” or “C plus-and-minus.” Whatever you call it, C++ requires careful attention to reap its advantages and avoid its problems. Starting on the Right Foot Right off the bat, C++ simplifies comments and avoids the danger of the “runaway comments” I described in Chapter 3. If you use // for comments everywhere but in macro definitions, you won’t have to worry about where the comment ends — it’s always at the end of the same source line. And look how clean comments appear: strcpy( title, name ); // Build title Unfortunately, some C++ compilers’ preprocessors may not strip comments from macro definitions, so the following sequence can create problems: #define MAX_FILES 10 // Limit to open files ... if ( file_cnt < MAX_FILES ) { ... } The problem arises if the preprocessor stores the replacement text for MAX_FILES as “10 // Limit to open files”. The expanded if statement then becomes if (file_cnt < 10 // Limit to open files ) { ... } which won’t compile. Your Constant Companion Another one of C++’s “pluses” helps here. In most cases, you can—and should—use const variables instead of macros to define mnemonics for constant values. In the example above, if you use const int MAX_FILES = 10; // Limit to open files instead of the #define, the comment poses no problem. Another advantage of const variables over macros is that the compiler parses the variable name and places it in the program’s symbol table, which allows the variable to be type-checked when referenced and to be used by cross-reference and debugger tools. Also, like other variables, const variables can have restricted visibility, thus avoiding name clashes between different sections of code. One place where you have to use a C++ “trick” instead of const is when you want to declare a constant within the scope of a class. The following syntax is illegal because you can’t assign an initial value to a static class member: class file_list { static const int MAX_FILES = 10; // Illegal! char * file_name[ MAX_FILES ]; }; A workaround can be used for integer constants by defining an enumeration containing the symbol and its value: class file_list { enum { MAX_FILES = 10 }; // Legal char * file_name[ MAX_FILES ]; }; As the above example shows, C++ has some helpful refinements over C, but maintains the C tradition of complex usage rules. If you aren’t convinced that C++ adds complexity, as well as capability, consider the rest of the story on static class members. Because a C++ class is a type, not a data object, and only one copy of a static class member exists (unlike non-static class members, which have one instance per object of the class), you have to define and initialize static members outside the class definition. class classX { static int objX_cnt; // Can't initialize here! }; ... int classX::objX_cnt = 0; // Initialize here. And you can’t use static in the objX_cnt variable definition because that would conflict with the use of static for global (not member) objects. If these rules seem burdensome, prepare yourself for the full force of C++, because this is just the beginning. The Calm Before the Storm Before examining the less pleasant side of C++, let’s consider some of the other advantages it offers over C. You can reduce the use of function-like macros, and thus avoid many of the pitfalls I described in Chapter 7, by using in-line functions and templates instead. Functions defined inside a class or with the in-line specifier can be compiled into in-line code, rather than a normal function call (the decision is left to the compiler). This technique lets you use in-line functions instead of equivalent macros — avoiding macro pitfalls but keeping their performance. Because you can control whether a member function that’s defined outside its class declaration is in-line or not, it’s good practice to define all member functions outside their respective class declaration. Following this rule also keeps your class definitions more compact and readable. For example, use class classX { inline int f( void ); }; inline int classX::f( void ) { ... } rather than class classX { int f( void ) { ... } }; In general, use in-line functions sparingly. The performance savings from eliminating a function call can easily be lost as code size expands. C++ templates are another one of its true bright spots. They provide a way to implement a generic piece of code that can work on different data types. This eliminates many of the places in C where a complex macro would be used instead of a function, so that the code can work with more than one type. Templates are also much simpler to use than some of the advanced C++ techniques for writing functions that can handle multiple types. Previous Table of Contents Next Copyright © NEWS/400 Books

Wyszukiwarka

Podobne podstrony:
069 072
Arkusz GM 4 072 (2)
Arkusz GM 7 072 (2)
069 Czekając na Bestię
v 04 072
072 073
czynnosci IT OUG UGBKUE t uj072009
072 075
072 074
C B 069
072 zadania

więcej podobnych podstron