Team LiB
Previous Section Next Section

3.1. Namespace using Declarations

3.1. 命名空间的 using 声明

The programs we've seen so far have referred to names from the library by explicitly noting that the name comes from the std namespace. For example, when we want to read from the standard input, we write std::cin. Such names use the :: operator, which is the scope operator (Section 1.2.2, p. 8). This operator says that we should look for the name of the right-hand operand in the scope of the left-hand operand. Thus, std::cin says that we want the name cin that is defined in the namespace std. Referring to library names through this notation can be cumbersome.

在本章之前看到的程序,都是通过直接说明名字来自 std 命名空间,来引用标准库中的名字。例如,需要从标准输入读取数据时,就用 std::cin。这些名字都用了:: 操作符,该操作符是作用域操作符(第 1.2.2 节)。它的含义是右操作数的名字可以在左操作数的作用域中找到。因此,std::cin 的意思是说所需要名字 cin 是在命名空间 std 中定义的。显然,通过这种符号引用标准库名字的方式是非常麻烦的。

Fortunately, there are easier ways to use namespace members. In this section we'll cover the safest mechanism: using declarations. We will see other ways to simplify the use of names from a namespace in Section 17.2 (p. 712).

幸运的是,C++ 提供了更简洁的方式来使用命名空间成员。本节将介绍一种最安全的机制:using 声明。关于其他简化使用命名空间中名字的方法将在第 17.2 节中介绍

A using declaration allows us to access a name from a namespace without the prefix namespace_name::. A using declaration has the following form:

使用 using 声明可以在不需要加前缀 namespace_name:: 的情况下访问命名空间中的名字。using 声明的形式如下:

     using namespace::name;

Once the using declaration has been made, we can access name directly without reference to its namespace:

一旦使用了 using 声明,我们就可以直接引用名字,而不需要再引用该名字的命名空间。

     #include <string>
     #include <iostream>
     // using declarations states our intent to use these names from the namespace std
     using std::cin;
     using std::string;
     int main()
     {
      string s;       // ok: string is now a synonym for std::string
      cin >> s;       // ok: cin is now a synonym for std::cin
      cout << s;      // error: no using declaration; we must use full name
      std::cout << s; // ok: explicitly use cout from namepsace std
     }

Using the unqualified version of a namespace name without a using declaration is an error, although some compilers may fail to detect this error.

没有 using 声明,而直接使用命名空间中名字的未限定版本是错误的,尽管有些编译器也许无法检测出这种错误。

A Separate Using Declaration Is Required for Each Name

每个名字都需要一个 using 声明

A using declaration introduces only one namespace member at a time. It allows us to be very specific regarding which names are used in our programs. If we want to use several names from stdor any other namespacethen we must issue a using declaration for each name that we intend to use. For example, we could rewrite the addition program from page 6 as follows:

一个 using 声明一次只能作用于一个命名空间成员。using 声明可用来明确指定在程序中用到的命名空间中的名字,如果希望使用 std(或其他的命名空间)中的几个名字,则必须为要用到的每个名字都提供一个 using 声明。例如,利用 using 声明可以这样重新编写第 1.2.2 节中的加法程序:

     #include <iostream>
     // using declarations for names from the standard library
     using std::cin;
     using std::cout;
     using std::endl;
     int main()
     {
         cout << "Enter two numbers:" << endl;
         int v1, v2;
         cin >> v1 >> v2;
         cout << "The sum of " << v1
              << " and " << v2
              << " is " << v1 + v2 << endl;
         return 0;
     }

The using declarations for cin, cout, and endl mean that we can use those names without the std:: prefix, making the code easier to read.

对 cincout 和 endl 进行 using 声明,就意味着以后可以省前缀 std::,直接使用命名空间中的名字,这样代码可以更易读。

From this point on, our examples will assume that using declarations have been provided for the names we use from the standard library. Thus, we will refer to cin, not std::cin, in the text and in code examples. To keep the code examples short, we won't show the using declarations that are needed to compile the examples. Similarly, our code examples will not show the necessary #include directives. Table A.1 (p. 810) in Appendix A lists the library names and corresponding headers for standard-library names we use in this primer.

从这里开始,假定本书所有例子中所用到的标准库中的名字都已提供了 using 声明。这样,无论是在文档还是在代码实例中引用 cin, 我们都不再写为前缀形式 std::cin,为了使代码实例简短,我们还省略了编译时所必需的 using 声明。同样的,程序实例也会省略必需的 #include 指示。本书附录 A中的表 A.1 列出了本书中用到的标准为名字的库名和相应的头文件。

Readers should be aware that they must add appropriate #include and using declarations to our examples before compiling them.

在编译我们提供的实例程序前,读者一定要注意在程序中添加适当的 #include 和 using 声明。



Class Definitions that Use Standard Library Types
使用标准库类型的类定义

There is one case in which we should always use the fully qualified library names: inside header files. The reason is that the contents of a header are copied into our program text by the preprocessor. When we #include a file, it is as if the exact text of the header is part of our file. If we place a using declaration within a header, it is equivalent to placing the same using declaration in every program that includes the header whether that program wants the using declaration or not.

有一种情况下,必须总是使用完全限定的标准库名字:在头文件中。理由是头文件的内容会被预处理器复制到程序中。用 #include 包含文件时,相当于头文件中的文本将成为我们编写的文件的一部分。如果在头文件中放置 using 声明,就相当于在包含该头文件 using 的每个程序中都放置了同一 using,不论该程序是否需要 using 声明。

In general, it is good practice for headers to define only what is strictly necessary.

通常,头文件中应该只定义确实必要的东西。请养成这个好习惯。



Exercises Section 3.1

Exercise 3.1:

Rewrite the program from Section 2.3 (p. 43) that calculated the result of raising a given number to a given power to use appropriate using declarations rather than accessing library names through a std:: prefix.

用适当的 using 声明,而不用 std::,访问标准库中名字的方法,重新编写第 2.3 节的程序,计算一给定数的给定次幂的结果。


Team LiB
Previous Section Next Section