C + + anonymous namespaces

Source: Internet
Author: User
Tags mutex

When you define a namespace, you can omit the name of the namespace:

namespce {char C;         int i;     Double D; The compiler internally generates a unique name for the namespace, and also generates a using directive for the anonymous namespace.         So the above code in effect is equivalent to: namespace __unique_name_ {char C;         int i;     Double D;      } using namespace __unique_name_; The names declared in the anonymous namespace are also converted by the compiler, bound together with the only internal name that the compiler generates for this anonymous namespace (that is, __unique_name_ here). It's also important that That is, these names have the internal link property, which is the same as the link property of the global name declared as static, that is, the scope of the name is limited to the current file and cannot be linked by using an extern declaration in another file. If you do not advocate the use of global static declarations with a name that has the internal link property, the anonymous namespace can be used as a better way to achieve the same effect. Attention:namespaces are all external connection properties, but anonymous namespaces produce __unique_name__ that cannot be found in other files, and this unique name is not visible.The new standard for C + + advocates the use of anonymous namespaces, rather than static, because static is used in different places with different meanings, which can easily cause confusion. In addition, static does not modify class 。 a second article;
Today, I got a tip from Google's boss and learned a new usage: anonymous namespaces.
C + + also has an anonymous namespace to ensure that the generated symbols are local, so that for variables in the anonymous space, the outside is invisible.//test3.cppstatic void Bar () {}namespace//anonymous namespace {    float BAR2;    int foo;} Test4.cppextern int foo;extern void Bar (); extern float bar2; int main () {bar ();                    The external bar () is declared static, and the symbol is not linked here. Cannot access bar2 = 0.1f;          Outside of the anonymous space, which is not accessible here. Foo = 0xff;return 0;};/ /If the target of the test4 is linked to the target of the test3, these symbols are not actually found. The link will fail. The anonymous namespace is a C + + feature that, in contrast to the static declaration of C, can declare many variables and functions in an anonymous space. This saves you from adding static declarations to each variable and function. Essentially, the functionality of an anonymous space is the same as a static declaration.

For a large C-language software project, naming functions and global variables is not an easy task, since it is important to consider whether it is possible to conflict with code written by other programmers, mostly by adding a specific prefix to a set of function names for each module, such as Htrequest_setinternal, Htrequest_internal and so on. This makes it necessary for programmers to output some more characters each time they call these functions, although using the better IDE (Integrated development environment) does not take much responsibility for the programmer's input, but these characters still seem redundant. So C + + introduces the concept of namespace, organizing some identifiers in a namespace-tree structure to make the code look more elegant. And it turns out that this feature is advanced, that it works well for large projects, and that later programming languages such as Java, C #, and Python support such features, but some are called different.

Namespaces can be used not only for organization types (class, struct, Enum), but also for organizing global variables, global functions, and so on. As shown in the example [2-1], the identifiers of different modules are organized into separate namespaces to avoid conflicting identifiers.

routine [2-1]

#include <iostream>

Namespace sock{

typedef unsigned short socket_port_t;

Const char* LOOPBACK_ADDR = "127.0.0.1";

Const socket_port_t Defualt_http_port = 80;

}

int main (void)

{

std::cout<< "Local HTTP addr =" <<sock::loopback_addr

<< ': ' <<sock::D efualt_http_port<<std::endl;

return 0;

}

Using namespaces in large C + + projects such as Google Chrome chorme, open source C + + library boost, and not using namespaces is an example of an open source C + + library Ace (the ADAPTIVE communication Environment), it chooses to prefix "Ace_" in front of each type, which makes the identifiers longer and looks somewhat redundant. For ease of use, and without modifying the ACE's source code, these identifiers can be renamed using typedef identifiers, as shown in routine [2-2]. Note that you cannot use # define here, because macros are not limited by namespaces.

routine [2-2]

#include <ace/Mutex.h>

Namespace ace{

typedef Ace_mutex mutexes;

typedef ace_lock Lock;

}

1.1.2. How to refer to identifiers within the command space

When the referenced identifier is not within the current namespace or global namespace, there are three ways to reference the identifier, such as the type of the mutex in the newly defined ACE command space in the previous section:

Way One

Ace::mutex Mutex;

Way Two

Using Ace::mutex;

Mutex mutex;

Mode three

using namespace Ace;

Mutex mutex;

Method one only when necessary through the domain operator ":" refers to identifiers within the specified command space, applies to the current compilation unit reference ACE within the identifier is not many, and the compilation unit uses these identifiers in a few cases.

Mode two introduces only Ace::mutex an identifier, which is recommended if you use Ace::mutex more times within the current compilation unit and do not conflict with identifiers in the current namespace.

The third approach is to introduce all identifiers in the Ace namespace into the current namespace, after which all the identifiers of the ace are visible to the current namespace, which increases the risk of identifier collisions. You can use this method to reduce the input of characters if the current compilation unit uses more identifiers in the Ace command space, and there is no problem with identifier collisions.

For the above three ways, it is recommended that the first choice, which is the least likely to generate identifier collisions, the way two times, as far as possible without a third Test, even for the C + + standard library do not use a third way, because at least in the Solaris system is a struct type called map??, If you reference a header file that contains this type, you will cause a naming conflict.

In addition, it is not recommended to use the using statement in the header file to introduce identifiers, otherwise these identifiers will be exposed to all the compilation units that refer to the file, which makes it easy for namespaces to lose their role in naming conflicts.

For the system API used, the recommended function name is distinguished by using the domain operator, which makes the program more readable, such as::: GetLastError (),:: GETCWD ().

Note that you should not refer to the system header file in a custom namespace, as shown in routine [2-3], to avoid confusing identifiers.

routine [2-3]

Namespace my_space{

#include <net/if.h>

}

1.1.3. Aliases for Command spaces

When the namespace to be referenced is long and you want to refer to the entity in the namespace in the first way, you can use a namespace alias to give the original namespace a short name, such as [2-4].

routine [2-4]

Namespace long_namespace{

void func (void) {/* Function body */}

}

namespace ns = Long_namespace;

int main (void)

{

Ns::func ();

return 0;

}

1.1.4. Anonymous command space

When the name namespace is declared empty, the namespace is an anonymous namespace (unnamed namespace). Anonymous space is a new alternative to using the static definition scope as a global or global variable for this compilation unit, and anonymous spaces can be nested as well as named namespaces. Because the anonymous namespace does not have a namespace name, it cannot be declared through extern within other compilation units, and the variable is naturally visible only within this compilation unit, such as routine [2-5].

routine [2-5]

#include <iostream>

using namespace Std;

namespace{int i = 256;}

Namespace ns{

namespace {int i = 128;}

void func (void)

{

cout<< "Ns::func:" <<endl;

cout<< "\t::i=" <<::i<<endl;

cout<< "\tns::i=" <<i<<endl;

}

}

int main (void)

{

cout<<::i<<endl;

cout<< "i=" <<i<<endl;

cout<< "ns::i=" <<ns::i<<endl;

Ns::func ();

return 0;

}

Using anonymous space has at least two advantages over using static:

1) for a set of more than one identifier function only need to use an anonymous space to declare, do not need to enter static multiple.

2) can be nested. This allows multiple identifiers with the same name to be used in different namespaces.

In the C + + standard, it is also recommended to use an anonymous namespace to define the global variables within the compilation unit, instead of the Static,static keyword is considered to be an outdated (deprecated) feature here.

C + + anonymous namespaces

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.