The C ++ Programming Language Chapter 8 Notes

xiaoxiao2021-03-06  22

THE C Programming Language Chapter 8 Note Name Space and Abnormal James Chen050320

8.1 Memorable and interface temporarily

******************* 8.2 name space *********************************

Namespace is a mechanism for describing logical packets. That is, if some declarations are logically identified by some guidelines, they can put them in the same name space to indicate this fact. Such as menus edit: namespace edit {void copy (char) {} void paste (char) {} void delete (char) {}} namespace file {void open (); void save (); Void exit ();} For the definition of members within the namespace, in general, it should be placed outside the namespace and declaration: Namespace Edit {Void Copy (char); void cut (char); void delete (char); void edit :: copy (char x) {} void Edit :: cut (char x) {} void Edit :: paste (char x) {} void Edit :: delete (char x) {} After the statement is separated from the definition, the user see is only a statement, and the function body will be placed, and the user does not need too much attention. Note that each function can only declare and define.

The namespace members must declare in space, can't introduce new members outside the namespace: void Edit :: Search (char); // Wrong, must be declared in Namespace.

The definition of the namespace member function must follow the function guidelines: void edit :: cpoy (char x) {} // is wrong, there is no cpoy () void Edit :: CUT (int a) {} // fault, requirements Centrophe as char

A NameSpace is also a scope. Conventional local scope, global scope and classes are also Namespace. Ideally, each entity in the program belongs to a logical unit that can be identified, so each declaration in a good program should be in a name space, indicating that it is played in the program. Character.

8.2.1 Name with qualified words Because the namespace is a role domain, the normal scope rule is also established for the namespace. Therefore, if a name is previously declared in this name space or its peripheral scope, it can be used directly, no need to further worry about it, or use the name from another name space, but you need to use it The name space belongs to the name belongs to the qualifier. Such as: void Edit :: Copy (CHAR X) {CUT (x); // Does not need limited words, because Cut and Copy are in the Edit name space file :: open (); // open is in the file, so Qualifiers}

8.2.2 Use the declaration When a name is frequently used in its own name space, each time you use to add a qualifier, which is really annoying, such as void Edit :: Copy (char X) {CUT x); file :: open (); file :: open (); file :: open (); file :: open (); .....}

Repeated writing qualifiers are very annoying, these excess things can be removed through a "use declaration", such as: void Edit :: Copy (char X) {using file :: open; // Using Open of File Member CUT (X); Open (); open (); open (); open ();

If A Namespace uses members in B NameSpace, we can put the relevant use declaration in a definition of A, such as: Namespace Edit {Void Copy (Char); Void Cut (char); void delete (char); using file :: open; // Using Open members in File} Void Edit :: Copy (CHAR X) {CUT (x); open ();} We can complete Open as EDIT's internal member is used without having to do it is from other members. 8.2.3 Using the instruction A "Usage Instruction" can turn all the names of a namespace into available, in the user's view, almost the same name. Such as: Namespace Edit {Void Copy; Void Cut (char); void delete (char); using namespace file; // Using all the names from File can be used} Void Edit :: Copy (char x) {CUT (X); open (); exit ();

8.2.4 Multi-interface

The role of the interface (interface) is to minimize interdependence between different parts of the program. The smallest interface will make the program easy to understand, have a good data concealed nature, easy to modify, but also compile faster. Namespace edit {void copy (char *); void cut (char *); Namespace file {void open (); void save ();} namespace EF_INTERFACE {Using Edit :: Copy; Using Edit :: cut; using file: : open; using file :: save;} We use the Edit / File member in EF_Interface, and open it to the user, and the user uses the EFT / FILE member through EF_ITERFACE. Of course, you can also add members in EF_INTERFACE to use Edit / File members, such as: Namespace EF_ITERFACE {void copy (char *); void open (); void save (); Void EF_INTERFACE :: Copy (char * a) {edit :: copy (a);} void EF_INTERFACE :: Cut (char * a) {edit :: cut (a);} void EF_INTERFACE :: open () {FILE: : Open ();} void ef_interface :: save () {file :: save ();} Indirect use of another way. Halo, this section does not understand. . . .

8.2.5 Avoid name conflicts

The namespace is to represent a logical structure. The simplest such structure is the code written by one person written with another person. When we combine from mutually independent portions, if there is the same name in these separate modules, conflicts, consider: //my.hchar f (char); int F (int); // Your.hchar f (char); int F (int); after these definitions, the third party is difficult to use my.h and Your.h. A very obvious solution is to include each set of declarations in their respective namespace: //my.hnamespace my {char f (int G (int);} // Your.hnamespace your {char f ); int G (int);} Now you can use the declaration in a third party, use the instructions to use the declarations in My.H and Your.h, such as: #include "my.h" #include "your.h "Using my :: f; using your :: g; void main () {char A = f ('a'); // use f; char b = Your :: f ('a') using my.h; ; // Use the f} in your.h, you can use the first Using Namespace MY, use your Your space to use, use the qualitative word your :: . 8.2.5.1 Nameless namespace Namespace {Int a; void f ();} equivalent to: Namespace $$$ {Int a; void f ();}

8.2.6 Name Find a function of taking T type parameters often defines the same name space with the T type itself. Therefore, if we can't find it in an environment using a function, let's see the namespace where its parameters are located, such as: Namespace aa {class Date {}; Bool Operator == (Const Date &, Const std :: string&) ; std :: string format;} void f (aa :: date d, int i) {std: string s = format (d); // ok, aa :: format (d) std: string t = format (i); // is wrong, there is no format (int)} in the scope}

With explicit use defining ratios, this lookup rule can save programmers save a number of inputs, and will not pollute the namespace in such a way as "use instructions". This rule is especially useful for operator computing objects and template parameters, because it is very troublesome to use explicit qualifiers there. Note that the namespace must be in the scope, and the function must also be declared before it is looking for and used. A functional ginsence can come from multiple namespaces, such as:

Void F (aa :: date d, std :: string s) {= {(d == s) {...} else if (d == "August 4,1914") {...}} for this Situation, we will find functions in the namespace of each parameter (including the classes and base classes of each parameter) in the called scope, and then perform a normal overload resolution rule for all functions found. For D == s above, we will find an operator of the most area D == S in the F () STD and AA, there is an operator == in the STD, but it is not Date and string are parameters, while the Operator == of AA is DATE, STRING as a parameter, so use aa :: Operator ==. When a member of a class calls a naming function, the function lookup should be partially biased with other members of the same class and its base class, not a function that may be discovered based on the type of other parameters. 8.2.7 name space alias

If the user gives them a very short name, the names of the different namespaces may also conflict: Namespace a {// A is too short, easy to cause conflict clars String {};} a :: string s1 = "asdfasf" ; A :: string s2 = "kjlegd";

However, in actual long code by the name it is not very easy: namespace Akfsdlflksldflksdflj {// is too long, inconvenient to use class String {};} Akfsdlflksldflksdflj :: String s3 = "asdfasf"; Akfsdlflksldflksdflj :: String s4 = " KJHLEGD "

This kind of two difficulties will be solved by taking alias for long name words: Namespace asa = akfsdlflksldflksdflj; // Take alias for long name,, a bit reference to feel ASA :: string s3 = "asdfasf"; asa :: string s4 = "kjhlegd";

The namespace alias also enables users to reference "a library", and define the library through the only declaration: Namespace lib = Foundation_Library_v2r11; lib :: set s; lib :: string S5 = "sdfsfsf"; use LIB instead of Foundation_Library_v2r11, which makes the program greatly simplified, and the code maintenance has become simple. When updating to the new version, just redefine the alias, without the need to modify it.

Of course, too much use alias will also quote confusion.

8.2.8 Space combination We often need to combine new interfaces from the existing interface, such as: Namespace his_string {class string {/*..../}; string operator (const string &, const string &); string Operator (const string &, const char *); void fill (char); // .....}

Namespace Her_vector {Template class vector {/*...*/}; // ....}

Namespace my_lib {usingspace his_string; using name_fct (string&);} With this, we can write programs on my_lib's basis: void f () {my_lib :: string s = "byosdf"; / / Use my_lib :: his_string :: string // ...} using namespace my_lib; void g (Vector & VS) / / equivalent to VOID G (Vector & vs) {// ... my_fct (vs [5]); // call MY_LIB:: MY_FCT (vs [5]) // ...} If the explicit name (such as String) is said There is no declaration in the namespace, the compiler will go to view the namespaces of "Using the Instruction" (such as his_string). According to Ideal, a name space should be: [1] describes a collection of characteristic features with logical uniformity. [2] Do not provide users with access to unrelated feature. [3] Do not give users an obvious burden.

8.2.8.1 Sometimes we just want to choose a few names from a namespace, such as: Namespace His_String {class string {/*...*/}; string Operator (Const string &, const string &); string operator (Const String & Const char *);} However, unless I is his_string designer or maintainer, this practice will soon fall into chaos. Any "true" Hit_String defined modification will not be reflected in this statement. Through the "Use Declaration", you can make things that choose some feature from the namespace more clear:

Namespace my_string {using his_string :: string; using his_string :: Operator ; // Use any }

"Use Declaration" will bring each declaration of the specified name into the scope. In particular, through a "use declaration", all modifications of a heavy load function can be brought in. In this manner, if the His_String's maintainer adds a member function to the String, or the operator adds an overload version, this modification will become a user-available thing that MY_STRING. Conversely, if some features are deleted, the impact on my_string will also be checked out by the compiler.

8.2.8.2 Combination and Selection The combination (using instructions) and selection (using declaration) can get more flexibility. Considering: Namespace His_LIB {Class String {/*...*/}; template class vector {/ *...*/}; // ...} Namespace Her_lib {class string {/ * .. . * /}; Template class vector {/ *...*/}; // ...} namespace my_lib {using namespace his_lib; // use everything from His_LIB Using Namespace HER_LIB; // Used All things from HER_LIB use his_lib :: string; // use stringusing her_lib :: vector; // from HER_LIB, using stringusing her_lib :: vector; // uses Vectortemplate Class List {/ // // ...} When viewing a name space, the explicit declared name (including the action declaration) takes precedence over the names that can be accessed in other scope. In this way, MY_LIB's users will see that parsing of String and Vector name conflicts are biased towards His_LIB :: String and Her_Vector. List always refers to MY_LIB :: List, regardless of whether there is a list in his_string and HER_Vector because of the overload. In general, when you introduce a name into a new name space, it is best to keep it unchanged, so we don't have to remember two names. Of course, this is not absolute, sometimes using new names will be better: namespace "{using namespace his_lib; using namespace mer_lib; using his_lib :: string; using her_lib :: vector; typedef HER_LIB :: string her_string; // name//......}

8.2.9 Namespaces and old code 8.2.9.1 name space and C

8.2.9.2 Namespace and overload overloading can work across the namespace. This feature is essential for what we can make existing wagemaked to use the namespace with the smallest price.

// Old A.hvoid f (int); // Old B.hvoid F (Char); // Old User.c # include "ah" #include "BH" Void g () {f ('a ');} // Call f () in BH ()

Upgrade it to the version using the namespace, no need to modify the actual code: // New A.hnamespace a {void f (int);} // New B.hnamespace B {Void f (char);} // New User.c # include "ah" #include "bh" Using namespace a; using namespace b; Void g () {f ('a');} // call f () in BH ()

8.2.9.3 The namespace is open name space is open, that is, you can declare it to it with multiple namespaces. For example: namespace a {int f (); // now A member f ()} Namespace a {Int g (); // Now there is F () and g ()} In this way, we can support A few large program fragments are placed in a name space, which is like the old libraries and applications exist in the same global name space. To do this, we must allow a name definition to distribute multiple header files and source code. //my.h // There are two functions, g () and f () void f (); # include int g (); // .... rewrite: //my.h }, f () Namespace Haha {Void f ();} # include Namespace Haha {Int g ();} // .... The names are minimal as possible, rather than putting the main fragments of the code into the same name space.

When defining a member that has already declared in a name space, the safer way is to use the Haha :: grammatical form instead of re-opening Haha. Such as: void haha ​​:: ff () // error, there is no Void ff () in Haha, the compiler can capture this error, however, because the new function can be defined in a space, the compiler cannot report an error! ! Such as: namespace haha ​​{void ff () //, FF is written as a new member to Haha {/*.....*/} The compiler does not know whether it is wrong, our intention is to define void f. (), Now the function is not defined, but also draw the snake. .

******************** 8.3 exception ******************* When a program is from some mutually When the separated module is composed, especially when these modules come from some independently developed libraries, the erroneous handles need to be divided into two independent parts: [1] One party reports those that cannot be locally resolved. [2] The other party handles errors that have been checked elsewhere.

Halo, you can see it, let's take a look.

8.4 Advice

[1] The logical structure is represented by the namespace. [2] Place each non-local name into a certain namespace, except for main (). [3] The design of the name space should make you easy to use it, but will not unexpectedly access other unrelated spaces. [4] Avoid using a short name for the namespace. [5] If necessary, the influence of the namespace name can be easily named through the namespace. [6] Avoid adding too much credits to your name space. [7] Use the Namespace :: MEMBER form when defining a member of the namespace. [8] Use using namespace only when converting, or in a local scope. [9] With an exception to relax "error" processing code and normal processing code. [10] Using user-defined types as an exception, no internal types. [11] When the local control structure is enough to cope with the problem, do not use anomalies.

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

New Post(0)