Effective C ++ 2e Item49

zhaozj2021-02-11  263

Terms 49: Familiar with the standard library

The C standard library is large. very large. Unbelievable big. How is Dafa? So, in the C standard, the specifications regarding the standard library account for more than 300 pages of dense Ma Ma, which does not include standard C libraries, the latter is just "as a reference" (honestly, the original text is used) C library.

Of course, it is not always the bigger better, but in the current situation, the bigger better, because the big library contains a lot of functions. The more features in the standard library, the more features that can be used when developing your own application. The C library is not provided (it is obvious that no support for concurrent and graphical user interfaces), but there is still a lot. Almost anything you can help it.

You need to introduce how it is organized before the standard library. Because the standard library is so much in the West, you (or anything else like you) is very likely to be the same as a certain name in the standard library. In order to avoid this conflict caused by this situation, everything in the standard library is placed in the namespace STD (see Terms 28). But this brings a new issue. Countless existing C code relies on the functions in the multi-year dummy standard library, for example, in the , , is functional. Existing software is not designed for the use of namespace. If you use STD to pack standard libraries, there is a shameful behavior. (This kind of cupping will make the programmer of the existing code to say that it is more difficult to listen to "shame")

Defend the destructive force that is an irritating programmer, the Standard Commission decided to create a new header name for the part of the standard library components that packaged STD. The method of generating a new head file is merely removed from the present C header file name. The method itself is not important. As the result, the result is not consistent, it is not important. So becomes , to become , and so on. For the C header file, use the same method, but you have to add a C before each name. Therefore, C becomes , becomes , and so on. The last point is that the old C header file is the official opposition (ie, clearly listed no support), but the old C header file is not (to maintain compatibility to C). In fact, compiler manufacturers do not stop providing support for customer existing software, so it is expected that the old C header file will still be supported in the next few years.

Therefore, in practice, the following is the status quo of the C header file:

· The old C header file name is will continue to be supported, although they are not in the official standard. The content of these headers is not in the namespace STD.

· New C header files such as The basic features containing the same and the corresponding old head files, but the contents of the header file are in the namespace STD. (In the process of standardization, some parts of the library have been modified, so the entities in the old head files and new headers do not necessarily correspond to it.)

• Standard C header files such as continue to be supported. The content of the header file is not in the STD. · New C header file with C library function has a name such as . The content thereof is the same as the corresponding old C header file, just in the STD.

All these first looks a little strange, but it is not difficult to get used to it. The biggest challenge is to clear the character serial file: is the old C header file, corresponding is based on Char * string processing functions; is a C header file packaged with STD, corresponding It is a new String class (see below); is the STD version corresponding to the old C header file. If you can master these (I believe you can), the rest will be easy.

About the standard library, the second point you need to know is that everything in the library is almost template. Look at your old friend iostream. (If you and iostream are not friends, go to clause 2, see why you want to develop relationships) iostream helps you operate the characters, but what is a character? Is Char? Is Wchar_T? Is a Unicode character? Some other multi-byte characters? There is no obvious answer, so the standard library makes you choose. All stream classes are actually class templates, specify the character type when instantification flow. For example, the standard library defines the COUT type as OSTREAM, but Ostream is actually a Basic_Ostream type definition (typedef).

Similar considerations apply to most of the other classes in the standard library. String is not class, it is a class template: Type parameters define the character types in each String class. Complex is not class, it is a class template: Type parameters define the type of real part of each Complex class and an imaginary part. Vector is not a class, it is a class template. So keep it.

In the standard library you can't avoid templates, but if you are interacted with a stream and string of char types and strings, you can usually ignore them. This is because of the char cases of these components, the standard library defines TypeDef for them, so you can continue using CIN, COUT, CERR, etc., and ISTREAM, OSTREAM, STRING, etc., do not worry about CIN The real type is Basic_istream and the true type of String is Basic_String .

The templateization of many components in the standard library is different from the above recommendations. Take a look at the concept that seems to be very intuitive. Of course, it can determine its parameters based on "it contains the character type", although different character sets are different, for example, special file end characters, copy their array, and so on. These features are called Traits in standards, which are specified by another template parameter in the String instance. In addition, String objects perform dynamic memory allocation and release, but there are many different ways to complete this task (see Terms 10). Which one is best? You have to choose: The String Template has an allocator parameter, the object of the Allocator type is used to assign and release the memory used by the String object.

Here is a complete statement of a Basic_String Template, as well as the string type definition (typef) that is built on it; you can find it in the header file (or something quite): Namespace std {

Template , class allocator = allocator > Class Basic_String;

Typedef Basic_String string;

}

Note that Basic_String Traits and Allocator parameters have default. This is a typical approach in the standard library. It provides users with flexibility, but for this flexibility, those "typical" users who only want to do "normal" operation can avoid it. In other words, if you just want to use a string object like a C-string, you can use String objects, without care that is actually an object with Basic_String , allocator > type.

Yes, you can usually do this, but sometimes you have to look at the bottom. For example, clause 34 indicates that a class does not provide a definition has advantages; it also points out that the following is an error method for declaring String type:

Class string; // will be compiled, but // you won't do this

Don't consider the namespace, the true problem here is that string is not a class, but a typedef. If you can solve the problem with the following method:

Typedef Basic_String string;

But this can't be compiled. "What is your Basic_String?" The compiler will be strange - especially, it may ask you in different statements. So, in order to declare the string, you must first declare all the templates it rely on. If you can do this, you will like this:

Template struct char_traits;

Template Class Allocator;

Template , class allocator = allocator > Class Basic_String;

Typedef Basic_String string;

However, you can't declare the string. At least there should be. This is because the standard library implemented Stirng (anything else in STD namespace) can be different from the standard, as long as the end-provided behavior meets the standard. For example, the implementation of Basic_String can increase the fourth template parameter, but the behavior of the code generated by the default value of this parameter is consistent with the original Basic_String described in the standard.

What should I do? Do not manually declare the String (or any other part of the standard library). Instead, only with an appropriate header file, such as . With these knowledge of header files and templates, you can now look at what major components in the standard C library:

· Standard C library. It is still there, you can use it. Although some places have a little small repairs, no matter how it is said, it is still the C library for many years.

Iostream. Compared with the implementation of "traditional" iostream, it has been templated, the inheritance hierarchy has also been modified, enhances the ability to throw an abnormal ability, can support String (through Stringstream class) and internationalization (via Locales --- - see below). Of course, you expect that there is almost all of the iostream library to continue. That is, it also supports the stream buffer, format the identifier, operator, and files, as well as CIN, COUT, CERR, and CLOG objects. This means that String and files can be done when streaming, and more widely controlled behavior, including buffering and formatting.

String. String objects are used in most applications to eliminate the use of Char * pointers. They support those operations you expect (for example, string connections, via Operator [] to constant time-level access, etc.), they can be converted to char * to keep and existing code compatibility, They also process memory management. Some String implementations use a reference count (see Terms M29), which brings better performance than char *-based strings (time and space).

• Container. Don't write your own basic containers! The standard library provides the following efficient implementations: Vector (like dynamically expandable arrays), List (Double List), Queue, Stack, Deque, Map, SET, and BitSet. Oh, there is no Hash Table (although many manufacturers are expanding), but how much can be used as compensation, String is a container. This is important because it means any operation made to the container (see below) to String is also applicable.

what? You don't understand why I said that the realization of the standard library is very efficient? Very simple: Standard library specifies the interface of each class, and part of each interface specification is a set of performance guarantees. So, for example, regardless of how the vector is implemented, it is not enough to provide access to its elements, but also access to "constant time". If so, it is not a valid VECTOR implementation.

In many C programs, dynamic allocation strings and arrays result in a large number of new and delete, new / delete errors -, especially for leakage caused by DELETE offs NEW, often happens. If you use String and Vector objects (both do their own memory management) without using Char * and dynamically assigned arrays, many new and delete can be free from use, and the issues that use them will also Disappear (for example, clauses 6 and 11).

· Algorithm. Standard containers are of course good, if there is a method that is easy to use them, it is better. The standard library provides a large number of easy ways (ie, predefined functions, officially referred to as algorithm ---- actually a function template), most of which apply to all containers in the library --- and Built-in arrays! The algorithm uses the contents of the container as a sequence, each algorithm, can be applied to a sequence corresponding to all values ​​in a container, or a subsequence (SUBSEQUENCE). Standard algorithm has for_each (a function to call each element in the sequence), Find (in the sequence containing the first position containing a value ---- Terms M35 show its implementation), count_if (calculated sequence In the amount of all the elements of the true element), Equal is exactly the same as the value of the elements contained in the two sequences), and the start position of a subsequence is found in a sequence), COPY (copy) A sequence to another), unique (delete the repetition value in the sequence), Rotate (value in the rotation sequence), SORT (value in the sequence). Note that there are only several algorithms in all algorithms; there are many other algorithms in the standard library.

Like the container operation, the algorithm also has a performance guarantee. For example, the Stable_Sort algorithm is required to do not exceed 0 comparisons (N log n) when executed. (If you don't understand the meaning of the symbol "0" above, don't be nervous. Summary, it means that it is actually that Stable_sort provides the performance and the most efficient generic sort algorithm at the same level.)

· Support for internationalization. Different cultures act in different ways. Like the C library, the C library provides a number of features that help to develop international software. However, although it is similar to that in concept, the method of C is still different. For example, C has used templates for support internationalization, and uses inheritance and virtual functions, which will not make you feel strange.

The main components supporting internationalization are Facets and Locales. Facets describe which features to process, including sorting rules (ie, how to sort characters in a regional character set), how should the date and time indicate how the numbers and currency values ​​indicate, how to use the information identifier Map into (nature) clear language information, and so on. Locales bundles multiple groups of Facets together. For example, a local Locale will include many Facets, describe how to sort American English string, how to read and write dates and time, read and write money and digital values ​​in a suitable manner, and so on. For a Locales about France, it describes how to complete these tasks in the way French people habits. C allows multiple locales in the single program, so different sections in an application may use different specifications.

· Support for digital processing. Fortran's last day may be coming. The C library provides a template for the special array of FLOAT, DOUBLE or LONG DOUBLE, and special arguments designed for numeric programming. For example, objects of a ValaRay type can be used to save an element that can be aliasing. This makes the compiler more fully optimized, especially for vector computers. The standard library also provides support for two different types of array films, and provides algorithm computing inner product, partial sum, and adjacent Difance. · Diagnostic support. Standard library supports three error modes: C's assertion (see Terms 7), error number, exception. In order to help provide a certain structure for the exception, the standard library defines the following exception class hierarchy:

| --- Domain_ERROR | ----- logic_error <---- | --- invalid_argument | | --- length_error | | - out_of_rangeexception <- | | --- rge_error | Runtime_ERROR <- | --- underflow_error | --- overflow_error

The exception of the logic_error (or its subclass) type is a logical error in the software. In theory, such errors can be prevented by more careful programming. An exception to the runtime_error (or its subclass) is an error that can only be discovered when running.

You can use them like this, you can create your own exception class by inheritance, or you can do it. No one is forcing you to use it.

The content listed above does not cover everything in the standard library. Remember, there are more than 300 pages of specification. But it still shows you the basic profile of the standard library.

The standard library is generally referred to as standard template libraries (STL - - see Terms M35). There is actually the third component in STL ---- Itelant ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Iterative is a pin-like object that allows STL algorithms to work together. But now you don't need to figure out the iteration, because I am introduced here is the high-level description of the standard library. If you are interested in it, you can find an example of using it in terms 39 and m35.

STL is the most innovative part of the standard library, which is not because it provides containers and algorithms (although they are very useful), but because of its architecture. Simply, its architecture has scalability: you can add STL. Of course, the components in the standard library itself are fixed, but if you follow the specifications of STL build, you can write your own containers, algorithms, and iterations, allowing them to work with the standard STL components, just between the standard components themselves. Mutual work. You can also use others to comply with the STL specification, algorithm, and iterative, just like others using you. The reason why STL has innovative meaning is that it is actually not software, but a set of specifications. The STL components in the standard library are only the benefits that refine this specification can be embodied. By using components in a standard library, you can usually let you avoid designing your IO streams, String, containers, internationalization, numerical data structures, and diagnostics. This gives you more time and effort to pay attention to the real - important part of software development: implement software features that are different from your competitors.

转载请注明原文地址:https://www.9cbs.com/read-4423.html

New Post(0)