2.3.5. Declarations and Definitions
As we'll see in Section 2.9 (p. 67), C++ programs typically are composed of many files. In order for multiple files to access the same variable, C++ distinguishes between declarations and definitions.
就像我们在2.9 (p. 67)节看到的一样,典型的C++程序通常会由好多文件组成。为了使不同的文件都可以访问同一个变量,C++会区分变量的声明(declarations)和定义(definitions)。
A definition of a variable allocates storage for the variable and may also specify an initial value for the variable. There must be one and only one definition of a variable in a program.
变量的定义(definitions)会为这个变量分配存储空间,并且可能会为其指定一个初始化的值。在程序里,一个变量必须有一个,也只能有一处定义(definitions)。
A declaration makes known the type and name of the variable to the program. A definition is also a declaration: When we define a variable, we declare its name and type. We can declare a name without defining it by using the extern keyword. A declaration that is not also a definition consists of the object's name and its type preceded by the keyword extern:
变量的声明(declarations)会将变量的类型和名称传达给程序。当然,定义(definitions)也是一种声明:当我们定义一个变量的时候,我们当然也声明了他的名称和类型。我们可以通过使用“extern”关键字来声明(declarations)一个变量,而不用定义(definitions)它。声明(declarations)的形式就是在对象(变量)的名字和类型前面,加上关键字“extern”:
extern int i; // declares but does not define i
int i; // declares and defines i
An extern declaration is not a definition and does not allocate storage. In effect, it claims that a definition of the variable exists elsewhere in the program. A variable can be declared multiple times in a program, but it must be defined only once.
带“extern”关键字的语句属于声明(declarations),不是定义(definitions),他不会给变量分配内存。实际上,它是说明程序中的某处包含这个变量的定义。一个变量可以在程序中被声明(declarations)多次,但是只能被定义(definitions)一次。
A declaration may have an initializer only if it is also a definition because only a definition allocates storage. The initializer must have storage to initialize. If an initializer is present, the declaration is treated as a definition even if the declaration is labeled extern:
声明(declarations)时你可以给变量初始化。但是一旦你这样做,那么这句话也就变成了定义(definitions),因为只有在定义(definitions)的时候才会为变量分配内存。初始化的时候必然要为初始值分配存储空间。如果你在声明(declarations)的时候同时初始化了变量,即便“extern”关键字存在,这个语句也会认为是定义(definitions)。
extern double pi = 3.1416; // definition
Despite the use of extern, this statement defines pi. Storage is allocated and initialized. An extern declaration may include an initializer only if it appears outside a function.
不管有没有“extern”关键字存在,这条语句的作用也是定义(definitions)“pi”。变量已经被分配了内存,并且赋予了初始值。声明(declarations)只有在一种情况下可以被初始化,那就是当他被放置在函数外部的时候。
Because an extern that is initialized is treated as a definition, any subseqent definition of that variable is an error:
由于包含初始化的声明(declarations)语句会被认为是定义(definitions),所以如下的用法会被认为是错误的:
extern double pi = 3.1416; // definition
double pi; // error: redefinition of pi
Similarly, a subsequent extern declaration that has an initializer is also an error:
同样的,定义(definitions)后再使用同样的声明(declarations)也是错误的:
extern double pi = 3.1416; // definition
extern double pi; // ok: declaration not definition
extern double pi = 3.1416; // error: redefinition of pi
The distinction between a declaration and a definition may seem pedantic but in fact is quite important.
声明(declarations)和定义(definitions)之间的区别看似有些卖弄学问的嫌疑,但是其实是非常重要的。
Note
In C++ a variable must be defined exactly once and must be defined or declared before it is used.
笔记
在C++里,变量必须被定义一次,最多一次,至少一次,而且必须在使用前定义(definitions)或者声明(declarations)。
Any variable that is used in more than one file requires declarations that are separate from the variable's definition. In such cases, one file will contain the definition for the variable. Other files that use that same variable will contain declarations for but not a definition of that same variable.
任何一个在多个文件中都要用到的变量都需要在没有其定义(definitions)的文件里对其进行声明(declarations)。在这样的情况下,一般一个文件会包含该变量的定义(definitions)。其他用到该变量的文件就会包含该变量的声明(declarations),而不是定义(definitions)。
Exercises Section 2.3.5
Exercise 2.18:
Explain the meaning of each of these instances of name:
extern std::string name;
std::string name("exercise 3.5a");
extern std::string name("exercise 3.5a");
Exercises Section 2.3.5
Exercise 2.18:
解释下面每个例子的含义:
extern std::string name;
std::string name("exercise 3.5a");
extern std::string name("exercise 3.5a");