static关键字对对象存储期和链接期的影响

来源:互联网 发布:邮件客户端软件 编辑:程序博客网 时间:2024/05/22 02:04

在看这篇文章之前,先问自己一个问题:加上static关键字后的名字可能拥有外部链接期吗?如果你已经很确定地知道答案,并且和这篇文章的最后结论相同,那么恭喜你,不用看这篇文章了,因为我将要讲的你都知道了。

影响对象的“存储期”

存储期,又称storage duration,是指变量所占用内存空间的生命期。也就是说,它决定了在整个程序的执行过程中该空间必须存在的时间段。它大于等于对象的生命期。C++03定义的存储期包括static(静态存储期)、dynamic(动态存储期)和automatic(自动存储期)。

static关键字对对象存储期的影响主要反映在局部变量上。

void f(){    // Automatic storage duration    int i = 10;    // Static storage duration    static int j = 10;}

变量 i 具有自动存储期,也就是说存放 i 的空间从左括号{开始, 到右括号} 结束。(注意,大多数编译器都会在一个局部作用域(block)开始的时候通过加减栈指针寄存器(SP/ESP/RSP)来为用到的局部变量分配所需的栈空间。所以,实际空间从 { 就开始存在了,而非定义处。)相比之下,加了static的变量j具有静态存储期,它的空间从程序载入直到程序结束始终存在。

影响对象的“链接期”

链接期,又称linkage,控制着对象的可见性。它和作用域(scope)的区别是:作用域决定了在同一个编译单元(包含头文件以后的源文件)中该对象的可见性。而链接期决定了跨多个编译单元时对象的可见性。C++03定义的链接期包括external(外部链接期)、internal(内部链接期)、no(无链接期)。

static关键字对对象链接期的影响主要反映在全局变量、函数上。

// A.cpp// External linkage by defaultint i = 10;// Internal linkagestatic int j = 10;// B.cppextern int i;extern int j;int main(){    int x = i;    // Link eror below! Unresolved external symbol "j".     // int y = j;}

全局变量默认具有外部链接期,就是全局可见——在其他编译单元(这里是B.cpp)中可见。加上static之后就变成了内部链接期,所以在其他文件中无妨访问,链接器报错。

函数就不举例了,一样的。加了static的函数只有本编译单元可以调用。

如果说到目前为止你都很清楚我说的,那么下面这个你可能觉得比较惊讶,static还可以使名字具有外部链接期!

// namespace scope class// MyClass.hclass MyClass{public:    // No linkage    int m_i;    // External linkage!    static int m_j;};// MyClass.cpp#include "MyClass.h"int MyClass::m_j = 10;// Another.cpp#include "MyClass.h"int main(){    MyClass::m_j = 20;    // Compile error below!    // m_i = 1;    // MyClass::m_i = 1;}

这里,普通的成员变量是没有任何链接期的,因为在它的作用域(class scope)以外无法通过名字m_i去直接访问它。但静态成员变量拥有外部链接期,所以可以直接在其他编译单元中访问,当然前提是加上类名限定(::)。

最后,顺便提一下,成员函数无论加不加static,都具有外部链接期。

原创粉丝点击