c++-namespaces

Source: Internet
Author: User
Tags aliases

From http://www.cnblogs.com/yabin/p/6411746.html1 modularity and interface

Any actual program is made up of some parts. By modularity of the program, we can make our programs clearer and help people cooperate and maintain.

After a program has been modularized, when one of the modules calls another module, it does not need to know its implementation, only need to invoke the interface it provides. So a module should be composed of two parts: the implementation and the interface provided to the outside.

2 The role of the namespace 2.1 namespace

A namespace is the equivalent of a container that contains a set of classes, templates, functions, and so on that are logically interconnected. That is, if some "objects" are logically related, we can put them into a namespace to distinguish them from the outside world. A notable feature of namespaces is that variables (classes, etc.) within a namespace can have names other than namespaces. This can be used to integrate code written by different people.
Namespaces are used in the following format:

namespace A{  void Fun1(){...}; void Fun2(){...};}

The above form of organization we put the specific implementation and declaration of the function together, sometimes we do not want to see the specific implementation of the function, just want to see all the functions of the interface interface. We can separate the interface of the function and the concrete implementation in the following way.

namespace A{  void Fun1(); void FUn1();}void A::Fun1(){/*...*/}void A::Fun2(){/*...*/}
    1. If the definition of a function is not in its corresponding namespace, you must use the scope resolver:: To specify the namespace of the function.
    2. You cannot define a new member that does not exist in a namespace outside of the namespace. For example:
void A:Fun3();    //错误,A里并没有Fun3()
    1. A good program should put all the entities (variables, classes, functions) in a program into a namespace. Except for the main () function, of course.
2.2 Namespace-scoped rules

A namespace is a scope, so it has regular scope rules.

    1. If a variable was previously declared in the namespace or its perimeter scope, it can be used directly.
    2. Using a variable from another namespace, you need to add a scope resolver.
    3. If you frequently use an entity from another namespace, you can use using to introduce it, and then use it without using the scope resolver.
double A::Fun(){  using B::Fun1;    //使用B命名空间的函数Fun1;  using C::Var1;    //使用C命名空间的变量Var1; void Fun1(Var1); //B::Fun1}
    1. The use of the external variable is scoped to the function, and if using is used in the namespace, the scope is extended to the entire namespace. If you use multiple entities in a namespace, you can introduce all the entities in the namespace directly with using namespace name, but it is not a safe practice to have all entities of a namespace accessible by another namespace, and should be avoided as much as possible.
namespace A{  using namespace B;    //使用命名空间B中所有实体}
    1. If there is a duplicate between the entities introduced by using the OR and the entities in this namespace. The addition of scope resolvers can help us better differentiate them.
2.3 Multi-weight interface

Sometimes we may need to provide a different interface to the same namespace when facing different users. For example, we have a namespace that defines some of the entities that are related to the serial port. The interfaces we provide to a developing program may include: Opening the serial port, setting the baud rate, setting the check digit, etc. But for an end user, we might just have to provide him with an open serial interface. This is the meaning of using multiple interfaces.

    1. There are many ways to implement multiple interfaces, and the first thing you might think about is using a different namespace.
namespace A{  void Fun1(); void Fun2(); void Fun3();}namespace A_Interface1{ using A::Fun1;}
    1. In the above interface implementation process, A_interface1 and a have a very strong association, modify the FUN1 in a will make A_interface1 Fun1 also modified. Sometimes we may not need such a strong correlation, so that the functions in the A_interface1 have a certain degree of controllability, you can use the following interface to implement the way.
namespace A{  void Fun1();  void Fun2(); void Fun3();}namespace A_Interface1{ void Fun1(){A::Fun1();}}

It is convenient to put the declaration and definition of FUN1 in A_interface1 together for the sake of writing. The above-mentioned interface implementation form to ensure that the A_interface1 in the Fun1 have a certain degree of autonomy, when a Fun1 change, we can in the A_interface1 of the Fun1 for further adjustment, Or simply don't use the Fun1 in a to re-implement the FUN1. This interface processing method to remove a certain degree of coupling, the basic has been able to meet most of the requirements.

3. Of course we can also not redefine a namespace directly using the name of the original namespace, but it is easy to mislead someone other than the program designer (let the person who sees this interface have only those entities declared in the namespace).

namespace A{  void Fun1(); void Fun2(); void Fun3();}//使用接口的文件包含下面这个声明或其所在的文件namespace A{ void Fun1();}
2.4 Nameless namespaces

We know that variable names can be duplicated in different namespaces, which helps a third party integrate code written by two different people. Sometimes we don't want some of our code to be integrated by others, but we also want to take advantage of the namespace--you can repeat the variable name. It is valuable to use the nameless namespace at this time: first there is no name, other places cannot be quoted; second, because it is a namespace the variables inside it can be duplicated with the names of variables in other namespaces.
Nameless namespaces can be called at this compilation unit (the same file), and no such rule will ever be used. It is important to note that the Nameless namespaces in different compilation units are different.

2.5 Compiler Name Lookup
    1. A function Fun1 If there is a parameter of type T, then in general the type T and function Fun1 are in the same namespace. When the compiler calls a function that uses the T parameter, it also implicitly looks for the called function from the namespace where T (and its base class) is located. The compiler's implicit look-up process allows programmers to omit many explicit qualifiers or using directives. And this lookup mechanism is particularly useful in the operator and template parameters of an object.
namespace A{  class TypeA{...};    void Fun1(TypeA a){...};}void Fun(A::TypeA a){ Fun1(a); //可以,会在TypeA所在命名空间A找到Fun1 Fun1(2); //不行}

Of course, the namespace itself must be in scope, and the function must be declared before it is found and used.

    1. If there are two arguments in the called function Fun1, and the FUN1 function is found in the namespace where both parameters are located. Then the overload resolution rule is invoked.
namespace A{  class TypeA{...};  bool operator==(const A&,std::string&);}void Fun(A::TypeA a,std::string str){ if(a == str) {...}}

In the previous example a==str , there are two data types in the expression, and the namespace A,STD for both data types defines operator== (the definition of the string operator is in STD), so overload resolution rules are called. Because Std::operator does not take TypeA as a parameter, all final compilers call a::operator==.
3. When a member of a class invokes a function, the compiler looks for the function in favor of finding the function in the same class and its base class, rather than in the namespace where the other parameter type of the called function is found. However, this rule does not apply to operators (such as +,-) lookups.

2.6 Aliases for namespaces

When we name a namespace, it is likely that there will be a conflict if it is too short (for example, a above). Too long and too troublesome. It might be better for us to take the name of a long named space in the appropriate place. The format is as follows:

namespace A = LongNameNamespaceA;

This substitution is very similar to the macro definition in C, so another special use of aliases is to make the code less dependent on the namespace. For example, we have a large program that relies on a namespace liba, and now requires a version upgrade to replace all code in reference Liba with Liba_plus. If we use aliases, we don't have to replace them with the one-by-look in the code LibA:: LibA_Plus . Instead, simply modify the alias definition of the namespace.

namespace A = LibA;//替换为namespace A = LibA_Plus;

However, it is also important to note that too much use of namespace aliases can cause confusion.

2.7 Combination of namespaces

We said earlier that namespaces can contain other namespaces, and here are some specifics of the namespace combination.

    1. Emphasize again that entities that are not declared in a namespace cannot be defined elsewhere. Even if the entity is declared in the namespace it contains.
namespace A{  using namespace B;}namespace B{  fill(char C);}A::fill(char C) //错误 A中并没有声明fill函数{...}
    1. When you introduce an entity of a namespace, you can introduce all of its overloads.
namespace B{  class String{...};  String operator+(const String&,const String&); String operator+(const String&,const char*);}namespace A{ using B::String; using B::operator+; //使用B中所定义的全部(两个)+运算}
    1. The display uses the Using keyword to change the order of the overloads.
Namespace liba{Class string{...};template<class t>class Vector{...}; //Other entities} namespace libb{class string{...}; template<class t> class Vector{...}; //Other entities} namespace libc{using namespace Liba; using namespace Libb; using liba::string; //favor the use of string Liba //inclined to use vector libb 
    1. Of course, if a string or vector is declared in libc, there is no relationship between Liba and Libb.
    2. If we want to use Libavector and libbstring that are overloaded with overrides. In addition to the scope resolver, you can use the form of a typedef and the form of inheritance.
template<class T>class A_Vector:public LibA::Vector<T>{...};typedef LibB::String B_String;
    1. Continued support for standard C libraries. In printf, for example, use the Std namespace in the C header file to wrap the stdio.h.
//stdio.hnamespace std{  int printf(const char*...);}using namespace std; //包含头文件后不需要再重复这句话了//...#include <cstdio> //对新库也进行包含using std::printf;

A new header file is provided in C + +, and the using directive is not used in the header file, which makes it possible to not want all of the standard library entities to be implicitly used.

//cstdio.hnamespace std{  int printf(const char* ...); //...}
    1. Namespaces are open, and you can add new members to the namespace in different files or in different places in the same file. It is also highly recommended to use this method to further classify namespaces, rather than putting all the entities into a large namespace.
//file1.cnamespace A{  int a;}//其他代码namespace A{ int b;}//file2.hnamespace A{ int c;}

c++-namespaces

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.