有各种各样的原因会用到类静态成员,一般是共享数据,但编写静态库的时候应慎重考虑,因为用在应用程序中没什么问题,但用在DLL中,可能灾难就开始了,看以下一个例子:
静态库中有一个名为TestSQL的数据库操作类,有一个静态成员m_count记录对某一数据库的访问记数,每有一次数据库操作就将该值加一。当然在静态库里会把这个值初始化为0:
int TestSQL::m_count = 0;
为了应付多线程操作的情况,该类内部很好地实现了同步处理机制。这样编程很方便,只要连接这个静态库,不管产生了多少TestSQL的对象,都能知道对数据库的操作次数。数据库操作很复杂,会执行一些存储过程,而且数据库存储过程可能会变,那相应调用代码也要变动,自然会想到把这些代码放到一个DLL,数据库存储过程变动,只要修改这个DLL的代码就行了。应用程序执行简单的数据库操作,当要执行存储过程就调用这个DLL。好,问题来了,应用程序执行了一个数据库查询操作,然后调用DLL执行一个存储过程,这时候这个静态m_count的值是多少?是2吗?错了,应用程序里是1,DLL里面也是1,即使是把EXE里的TestSQL对象作为参数传给DLL执行,也还是1,因为虽然是在同一个进程空间,但是编译器编译的时候,是把静态库连接进来,EXE和DLL分别有自己的int TestSQL::m_count,因此EXE和DLL是分别记数的,即使把EXE里产生的对象:TestSQL* sqlExe作为参数传递给DLL,但是在DLL里面执行sqlExe->数据库操作函数(),是在自己的m_count上记数,并不会改变EXE里的m_count值。
上面讲的这种情况还不会产生异常,如果静态成员是指针的话,就有可能会引起非法操作了,因此编写静态库的时候,应注意这个问题。