,
[ Pobierz całość w formacie PDF ]
176 C/C++ Language Reference Chapter 10. Namespaces A namespace is an optionally-named scope. You declare names inside a namespace as you would for a class or an enumeration. You can access names declared inside a namespace the same way you access a nested class name by using the scope resolution (::) operator. However namespaces do not have the additional features of classes or enumerations. The primary purpose of the namespace is to add an additional identifier (the name of the namespace) to a name. v C++ Scope Resolution Operator :: on page 77 Defining Namespaces In order to uniquely identify a namespace, use the namespace keyword. Syntax namespace namespace { namespace_body } identifier The identifier in an original namespace definition is the name of the namespace. The identifier may not be previously defined in the declarative region in which the original namespace definition appears, except in the case of extending namespace. If an identifier is not used, the namespace is an unnamed namespace. v Unnamed Namespaces on page 180 Declaring Namespaces The identifier used for a namespace name should be unique. It should not be used previously as a global identifier. namespace Raymond { // namespace body here... } In this example,Raymondis the identifier of the namespace. If you intend to access a namespace s elements, the namespace s identifier must be known in all translation units. v Global Scope on page 2 Creating a Namespace Alias An alternate name can be used in order to refer to a specific namespace identifier. © Copyright IBM Corp. 1998, 2001 177 namespace INTERNATIONAL_BUSINESS_MACHINES { void f(); } namespace IBM = INTERNATIONAL_BUSINESS_MACHINES; In this example, theIBMidentifier is an alias forINTERNATIONAL_BUSINESS_MACHINES. This is useful for referring to long namespace identifiers. If a namespace name or alias is declared as the name of any other entity in the same declarative region, a compiler error will result. Also, if a namespace name defined at global scope is declared as the name of any other entity in any global scope of the program, a compiler error will result. v Global Scope on page 2 Creating an Alias for a Nested Namespace Namespace definitions hold declarations. Since a namespace definition is a declaration itself, namespace definitions can be nested. An alias can also be applied to a nested namespace. namespace INTERNATIONAL_BUSINESS_MACHINES { int j; namespace NESTED_IBM_PRODUCT { void a() { j++; } int j; void b() { j++; } } } namespace NIBM = INTERNATIONAL_BUSINESS_MACHINES::NESTED_IBM_PRODUCT In this example, theNIBMidentifier is an alias for the namespace NESTED_IBM_PRODUCT. This namespace is nested within the INTERNATIONAL_BUSINESS_MACHINESnamespace. Extending Namespaces Namespaces are extensible. You can add subsequent declarations to a previously defined namespace. Extensions may appear in files separate from or attached to the original namespace definition. For example: namespace X { // namespace definition int a; int b; } namespace X { // namespace extension int c; int d; } namespace Y { // equivalent to namespace X int a; int b; int c; int d; } 178 C/C++ Language Reference In this example,namespaceXis defined withaandband later extended withc andd.namespaceXnow contains all four members. You may also declare all of the required members within one namespace. This method is represented bynamespace Y. This namespace containsa,b,c, andd. Namespaces and Overloading You can overload functions across namespaces. For example: // Original X.h: f(int); // Original Y.h: f(char); // Original program.c: #include "X.h" #include "Y.h" void z() { f('a'); // calls f(char) from Y.h } Namespaces can be introduced to the previous example without drastically changing the source code. // New X.h: namespace X { f(int); } // New Y.h: namespace Y { f(char); } // New program.c: #include "X.h" #include "Y.h" using namespace X; using namespace Y; void z() { f('a'); // calls f() from Y.h } Inprogram.c, functionvoidz()calls functionf(), which is a member of namespaceY. If you place theusingdirectives in the header files, the source code forprogram.cremains unchanged. v Chapter 11. Overloading on page 185 Chapter 10. Namespaces 179 Unnamed Namespaces A namespace with no identifier before an opening brace produces an unnamed namespace. Each translation unit may contain its own unique unnamed namespace. The following example demonstrates how unnamed namespaces are useful. #include using namespace std; namespace { const int i = 4; int variable; } int main() { cout variable = 100; return 0; } In the previous example, the unnamed namespace permits access toiand variablewithout using a scope resolution operator. The following example illustrates an improper use of unnamed namespaces. #include using namespace std; namespace { const int i = 4; } int i = 2; int main() { cout return 0; } Insidemain,icauses an error because the compiler cannot distinguish between the global name and the unnamed member with the same name. In order for the previous example to work, the namespace must be uniquely identified with an identifier andimust specify the namespace it is using. You can extend an unnamed namespace within the same translation unit. For example: #include using namespace std; namespace { int variable; void funct (int); } namespace { void funct (int i) { cout } 180 C/C++ Language Reference int main() { funct(variable); return 0; } both the prototype and definition forfunctare members of the same unnamed namespace. Note: Items defined in an unnamed namespace have internal linkage. Rather than using the keyword static to define items with internal linkage, define them in an unnamed namespace instead. v Program Linkage on page 4 v Internal Linkage on page 4 Namespace Member Definitions A namespace can define its own members within itself or externally using explicit qualification. The following is an example of a namespace defining a member internally: namespace A { void b() { /* definition */ } } Within namespaceAmembervoidb()is defined internally. A namespace can also define its members externally using explicit qualification on the name being defined. The entity being defined must already be declared in the namespace and the definition must appear after the point of declaration in a namespace that encloses the declaration s namespace. The following is an example of a namespace defining a member externally: namespace A { namespace B { void f(); } void B::f() { /* defined outside of B */ } } In this example, functionf()is declared within namespaceBand defined (outside B) inA. Namespaces and Friends Every name first declared in a namespace is a member of that namespace. If afrienddeclaration in a non-local class first declares a class or function, the friend class or function is a member of the innermost enclosing namespace. The following is an example of this structure: // f has not yet been defined void z(int); namespace A { class X { friend void f(X); // A::f is a friend }; Chapter 10. Namespaces 181 // A::f is not visible here X x; void f(X) { /* definition */} // f() is defined and known to be a friend } using A::x; void z() { A::f(x); // OK A::X::f(x); // error: f is not a member of A::X } In this example, functionf()can only be called through namespaceAusing the callA::f(s);. Attempting to call functionf()throughclassXusing the A::X::f(x);call results in a compiler error. Since the friend declaration first occurs [ Pobierz caÅ‚ość w formacie PDF ] |
Podobne
|