C++静态成员变量

今天在弄一段代码的时候遇到了静态成员变量的问题。卡了一段时间后,果断翻出《深入探索C++对象模型》,大概明白了问题所在。这事给我的一点启示就是“纸上得来终觉浅,绝知此事要躬行”。首先看看问题吧!其实就是一个类型的定义。代码如下:

//myApplication.cpp  
#include "myapplication.h"  
#include <iostream>  
using std::cout;  
using std::endl;  
  
myApplication::myApplication(string _appName):appName(_appName)  
{  
    if(self!=0)  
        return;  
    else  
        self=this;  
}  
void myApplication::printAppname()  
{  
    cout<<appName<<endl;  
}  
myApplication* myApplication::self=0;  
//myApplication.h  
#ifndef MYAPPLICATION_H_INCLUDED  
#define MYAPPLICATION_H_INCLUDED  
#include <string>  
using std::string;  
  
#define myApp myApplication::instance()  
  
class myApplication  
{  
public:  
    myApplication(string _appname);  
    static myApplication* instance() {return self;}  
    void printAppname();  
private:  
    static myApplication *self;  
    string appName;  
};  
  
#endif // MYAPPLICATION_H_INCLUDED  

        看到了myApplication* myApplication::self=0;这一行我就有点犯糊涂了。为什么要这样赋值呢?可不可以在类里面赋值呢?我试了试,答案是不可以的。查了一下C++规定了类的静态成员变量要在类外赋值。我有了疑问,为什么要这样规定呢?
        查阅《深入探索C++面向对象模型》,我找到原因。首先类的静态成员变量是被所有类成员共享的,在内存中应该只有一份拷贝。为了实现这种特性,C++把静态成员变量用全局变量来进行了实现,只是这个全局变量的可见范围在这个类里边。所以,与其说在类定义中定义了静态变量,不如说是引用了静态变量。而类外的初始化赋值其实包含了定义。我试了一下,去掉这个所谓的类外赋值,编译器就会报“undefined references to ...”错误。
        其次我还犯了另一个糊涂,静态变量是什么时候赋值的?我测试了一下,静态变量的赋值是在该类型的第一个对象被定义之前就已经完成了。到底是什么时候呢?其实转念一想,赋值语句其实并不一定要在运行时调用执行才能完成。编译、链接或者加载的时候就可以将这个“全局变量”初始化了”,应用程序运行之前,数据段的这个“全局变量”已经都被赋值好了。当然也有可能是通过.init段实现的。具体的情况以后再去深究了。

发表评论