Basic knowledge of namespaces in C + + programming _c language

Source: Internet
Author: User
Tags anonymous function definition

A namespace is a declarative region that provides a scope for its internal identifiers (names of types, functions, and variables). Namespaces are used to organize code into logical groups and can also be used to avoid name collisions, especially if the codebase includes multiple libraries. All identifiers within a namespace range are visible to each other without any restrictions. An identifier outside of a namespace can access a member by using the fully qualified name of each identifier (for example, std::vector<std::string> VEC;), or through the using declaration of a single identifier (using std::string) or the using directive (C + +) of all identifiers in the namespace (using namespace std;) To access the members. The code in the header file should always use the fully qualified namespace name.
The following example shows three methods that code outside of a namespace declaration and namespace can access its members.

Namespace Contosodata
{ 
 class ObjectManager 
 {public
 :
  void DoSomething () {}
 };
 void Func (ObjectManager) {}
}

Use fully qualified name:

Contosodata::objectmanager Mgr;
Mgr. DoSomething ();
Contosodata::func (MGR);

Use a using declaration to introduce an identifier to a range:

Using Widgetsunlimited::objectmanager;
ObjectManager Mgr;
Mgr. DoSomething ();

Use directive to bring all content in a namespace into scope:

using namespace widgetsunlimited;
ObjectManager Mgr;
Mgr. DoSomething ();
Func (MGR);

Using directives
with a using directive, you can use all the names in a namespace without requiring a namespace name to be an explicit qualifier. If multiple different identifiers are used in a namespace, use directives (that is, *.cpp) are used in the implementation file, and if only one or two identifiers are used, consider using declarations to introduce only those identifiers instead of all identifiers in the namespace. If the name of the local variable is the same as the name of the namespace variable, the namespace variable is hidden. It is an error to have the namespace variable the same name as the global variable.
attention
the using directive can be placed at the top of a. cpp file (within a file range) or within a class or function definition.
In general, avoid placing a using directive in the header file (*.h) because any file that contains the header introduces all of the contents of the namespace into scope, which results in a very difficult name-hiding and name-conflict problem to debug. In the header file, always use the fully qualified name. If these names are too long, you can shorten them using a namespace alias. (see below.) )
declaring namespaces and namespace members
Typically, a namespace is declared in a header file. If the function implementation is in a separate file, qualify the function name, as shown in this example.

ContosoData.h 
#pragma once
namespace Contosodataserver
{
 void Foo ();
 int Bar ();

}
Function implementations in Contosodata.cpp should use fully qualified names, even if a using directive is placed at the top of the file:
#include "contosodata.h"
using namespace Contosodataserver; 

void Contosodataserver::foo ()
{
 //no qualification because using directive above
 Bar (); 
}

int Contosodataserver::bar () {return 0;}

You can declare namespaces in multiple blocks in a single file, or you can declare namespaces in multiple files. The compiler joins parts together during the preprocessing process, resulting in a namespace containing all the members declared in all parts. A related example is the Std namespace declared in each header file in the standard library.
Members of the specified namespace can be defined outside of the namespace declared by the explicit qualification of the defined name. However, after the definition must appear in the namespace, the namespace is contained in the declared namespace. For example:

Defining_namespace_members.cpp
//C2039 expected
namespace V {
  void F ();
 }

 void V::f () {}  //ok
 void V::g () {}/  /C2039, G () isn't yet a member of V

 namespace v {
  g ();
 }
}

This error can occur when namespace members are declared across multiple-header files and are not included in the correct order.
Global namespaces
If an identifier is not declared in an explicit namespace, the identifier is part of an implicit global namespace. In general, if possible, try to avoid declaring globally, except for the entry point main function, which must reside in the global namespace. To explicitly qualify a global identifier, use a range resolution operator without a name, such as: SomeFunction (x); As shown in. This distinguishes the identifier from anything with the same name in any other namespace and helps make it easier for others to understand your code.
STD namespaces
all C + + standard library types and functions are declared in the Std namespace or in namespaces nested within the Std.
nested namespaces
namespaces can be nested. A normal nested namespace has unqualified access to its parent member, and the parent member does not have unqualified access to the nested namespace (unless it is declared inline), as shown in the following example:

Namespace Contosodataserver
{
 void Foo (); 

 Namespace Details
 {
  int countimpl;
  void Ban () {return Foo ();}
 }

 int Bar () {...};
 int Baz (int i) {return Details::countimpl}} 



An ordinary nested namespace can be used to encapsulate internal implementation details that are part of a public interface that is not a parent namespace.
Inline Namespaces (c + + 11)
Unlike normal nested namespaces, members of an inline namespace are treated as members of the parent namespace. This feature makes a parameter-dependent lookup for overloaded functions work with overloaded functions in the parent namespace and in the nested inline namespace. It also allows you to declare a specialization in the parent namespace of the template declared in the inline namespace. The following example shows how external code is bound to an inline namespace by default:

Header.h
#include <string>


namespace Test
{
 namespace Old_ns
 {
  std::string Func () { Return std::string ("Hello from old"); }

 Inline namespace New_ns
 {
  std::string Func () {return std::string ("Hello from New");
}}

#include "header.h"
#include <string>
#include <iostream>

int main ()
{
 using namespace Test;
 using namespace std;

 string s = Func ();
 Std::cout << s << std::endl; "Hello from new" return
 0;
}

The following example shows how to declare a specialization in the parent namespace of a template declared in an inline namespace:

Namespace Parent
{
 inline namespace New_ns
 {Template <typename t> struct
   C
   {
    T member;}
   ;
 }
  Template<>
  class C<int> {};
}

The

can use an inline namespace as a version control mechanism to manage changes to the library's public interface. For example, you can create a single parent namespace and encapsulate each version of an interface into its own namespace nested within the parent namespace. Namespaces that retain the latest or preferred version are limited to inline and are therefore exposed as direct members of the parent namespace. Client code that invokes Parent::class is automatically bound to the new code. By using the fully qualified path to the nested namespace that contains the code, you can still access the older version of the client by selecting it. The
Inline keyword must be applied to the first declaration of a namespace in a compilation unit.
The following example shows two versions of an interface, each of which is in a nested namespace. Some modifications have been made to the V_20 namespace through the V_10 interface, and the namespace is marked inline. Client code that uses the new library and calls Contoso::funcs::add will invoke the V_20 version. Attempt to invoke Contoso::funcs::D ivide code will now get a compile-time error. If they do need this function, you can still access the V_10 version by explicitly calling Contoso::v_10::funcs::D ivide.

Namespace Contoso
{
 namespace v_10
 {
  template <typename t>
  class Funcs
  {public
  :
   funcs (void);
   T Add (t A, t b);
   T subtract (t A, t b);
   T Multiply (t A, t b);
   T Divide (t A, T b);}
  ;
 }


 Inline namespace v_20
 {
  template <typename t>
  class Funcs
  {public
  :
   funcs (void) ;
   T Add (t A, t b);
   T subtract (t A, t b);
   T Multiply (t A, t b);
   Std::vector<double> Log (double);
   T accumulate (std::vector<t> nums);}
  ;
 }



name Space alias
namespace names must be unique, which means that they should not usually be too short. If the length of the name makes the code difficult to read, or if typing is tedious in a header file that cannot use a using directive, you can use the abbreviated namespace alias that is used as the actual name. For example:

Namespace A_very_long_namespace_name {class Foo {};}
namespace avlnn = A_very_long_namespace_name;
void Bar (Avlnn::foo Foo) {}

Anonymous or unnamed namespaces
You can create an explicit namespace, but do not provide a name for it:

namespace
{
 int MyFunc () {}
}}

This is called an unnamed namespace or an anonymous namespace, and is useful when you want to make variable declarations invisible to code in other files (that is, provide them with internal links) without having to create a named namespace. All code in the same file can see identifiers in unnamed namespaces, but the identifiers and namespaces themselves are not visible outside the file (or, more accurately, outside the translation unit).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.