2012-03-28 36 views
7
//a.h 

extern int x1; 
static int x2; 
int x3; 
static const int x4; 

class A { 
    public: 
     static const int x5 = 10; 
}; 

a.h const`将由多个.cpp文件包括在内,我的问题是:`static`,`extern`,`在头文件

1. x1只是一个声明,不是吗?所以它的定义应该在其中一个.cpp文件中完成,对吧?

2. x2是一个定义,对吧?我曾经认为static int也是一个声明就像extern int,但我错了。 x2只会在a.h中可见?

3. 将被定义多次,如果a.h包括在多个.cpp文件,因此会导致编译错误,对吧?

4. x4是一个定义,对吧?

5.在A级,x5是一个声明,是的。但是x4呢?

+0

你是什么意思的项目5的问题? – 2012-03-28 13:09:11

+0

@DavidHeffernan,我的意思是为什么'x5'是一个声明,但是'x4'? – Alcott 2012-03-28 13:11:39

回答

10

1.x1只是一个声明,不是吗?所以它的定义应该在其中一个.cpp文件中完成,对吧?

正确

2.x2是一个定义,对不对?我曾经认为静态int也是一个像extern int一样的声明,但我错了。 x2只会在a.h中可见?

不同的x2将在每个包含标题的翻译单元中可用。

如果a.h包含在多个.cpp文件中,3.x3会被多次定义,所以x3会导致编译错误,对吗?

更准确地说,它会导致链接器错误。编译器处理每个翻译单元,链接器将它们绑定在一起并检测该符号是多次定义的。

4。x4是一个定义,对吧?

是的,这是一个定义,但与x2每个翻译单元都会有它自己(因为x4static因为它是const这意味着内部链接

5.Here在A类中,x5是声明,是的,但是x4怎么办?

是的,x5是一个只有声明(有初始化)。因为关键字static在不同情况下被重复使用以表示不同的事物。在x5这意味着类的属性,而在x4这意味着内部联动

最后一种情况是特殊的。它是唯一声明(IIRC),声明可以有一个值,原因是它允许编译器在所有包含该头文件的翻译单元中将常量的值用作,编译时间常数为。如果该值必须与定义一起提供,那么只有一个翻译单位可以访问该值。静态成员的定义是:

const int A::x5; // no initialization here 

,您必须提供一个该成员是否ODR使用的。现在事实是,在大多数情况下,常数不会是odr-used,因为当使用表达式A::x5时,编译器将替换该值。只有当构件被用作左值您需要的定义,例如:

void f(const int &) {} 
int main() { 
    f(A::x5); 
} 

因为参数f是一个参考,使用A::x5需要左值(注意,常量性和左值/右值几乎是正交的),并且需要在程序中的单个翻译单元中定义成员。

+0

什么是“内部联系”? – Alcott 2012-03-28 13:15:41

+0

@Alcott:符号不能从定义它的翻译单元外部访问。这意味着如果多个翻译单元通过内部链接来定义具有相同名称的符号,则每个翻译单元将获得它们自己的不同符号(即,即使它们具有相同的名称也是不同的符号)。 – 2012-03-28 13:21:16

4
  1. 正确

  2. 这是一个定义,x2将为0,并且包含头将拥有自己的x2副本每个翻译单元。

  3. 是的,但它会导致链接器错误,而不是编译器。

  4. 与2.相同,但无法对其进行修改。

  5. 课内,static有不同的含义。这是合法的,因为x5是const整型,也是初始化的。

+0

那么'x2'不是一个可以在多个'.cpp'文件之间共享的全局变量吗? – Alcott 2012-03-28 13:12:36

+0

@LuchianGrigore:在一个单独的翻译单元中,您将其定义为“const int A :: x5;'(定义中不允许初始化)。如果你想验证这不是一个定义添加到程序:'void f(const int&){} int main(){f(A :: x5); }'你会得到一个链接器错误(直到你添加了定义)。 – 2012-03-28 13:13:40

+0

@Alcott no,x2对于每个'cpp'文件都是不同的。 – 2012-03-28 13:13:42

相关问题