当前位置 博文首页 > Allen Roson:使用static变量的注意事项
最近在两个部门的同事的代码中看到了一些关于static变量的错误用法,针对他们的错误用法,今天抽时间总结了一下,结论如下:
1.不用delete static修饰的指针,因为静态变量的生存周期和整个程序运行的周期是一样的,程序结束时静态变量占用的内存才被释放,在程序结束前,即使delete并且赋值为NULL了,该指针占用的内存也并未真正释放;
2.尽量不要在头文件中定义静态全局变量,static修饰的静态全局变量的作用域只存在于它被定义的代码文件中。如果在一个头文件中声明静态变量,那么每个包含该头文件的cpp都会存在这样一个全局变量,但他们都是独立的,作用域都只在各自的cpp中。如果要定义所有cpp共享的全局变量,那么在头文件中用extern修饰即可,但不要初始化。
?
运行下面的代码,可以证明上面的结论是正确的。
//StaticTest.h
#pragma once
static int g_iValue = 0;
class StaticTest
{
public:
StaticTest(void);
~StaticTest(void);
void AddValue();
void SetValue()
{
g_iValue = 5;
}
int GetValue()
{
return g_iValue;
}
};
//StaticTest.cpp
#include "StdAfx.h"
#include "StaticTest.h"
StaticTest::StaticTest(void)
{
}
StaticTest::~StaticTest(void)
{
}
void StaticTest::AddValue()
{
g_iValue += 2;
}
// Test1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include "StaticTest.h"
using namespace std;
class Test
{
public:
~Test()
{
}
static Test *GetInstance()
{
if(NULL == m_pInstance)
{
m_pInstance = new Test;
}
return m_pInstance;
}
void Func()
{
}
private:
Test()
{
}
public:
static Test *m_pInstance;
};
Test *Test::m_pInstance = NULL;
int _tmain(int argc, _TCHAR* argv[])
{
Test *pTest1 = Test::GetInstance();
pTest1->Func();
cout<<"pTest1的地址:"<<pTest1<<endl;
delete Test::m_pInstance;
Test::m_pInstance = NULL;
/*虽然上面Test::m_pInstance被delete并被赋值为NULL,并且在下面调用Test::GetInstance()时,m_pInstance的值
也确实为NULL,但是在执行完m_pInstance = new Test;这一句后,发现m_pInstance的值和第一次被new的值是一样的,
这说明m_pInstance并未被真正释放,它应该要直到程序结束时才会被释放*/
Test *pTest2 = Test::GetInstance();
pTest2->Func();
cout<<"pTest2的地址:"<<pTest2<<endl;
/*static int g_iValue被定义在StaticTest.h 中,然后被包含到StaticTest.cpp 这样做其实会导致StaticTest.cpp和
StaticTest.h中都有1个g_iValue,不过他们是的作用域是独立的,在StaticTest.cpp修改了g_iValue的值后,并不影响
StaticTest.h中的g_iValue的值*/
StaticTest objTest;
objTest.SetValue();//只影响StaticTest.h中的g_iValue的值
objTest.AddValue();//只影响StaticTest.cpp中的g_iValue的值
cout<<"g_iValue += 2后的值:"<<objTest.GetValue()<<endl;
return 0;
}
运行结果:
cs