【C++基础之一】静态变量的分配空间与LNK2001错误
今天写一个单例类,在使用静态变量的时候发现了一个之前没有注意到的问题,这里总结并记录一下。
先看这个单例类:
-
Singleton.h
-
-
-
class CSingleton
-
{
-
public:
-
~CSingleton(void);
-
static CSingleton* getSingleton();
-
int a;
-
private:
-
CSingleton(void);
-
static CSingleton* m_Singleton;};
-
Singleton.cpp
-
-
-
-
CSingleton::CSingleton(void)
-
{
-
a=3;
-
}
-
CSingleton::~CSingleton(void)
-
{
-
if(m_Singleton!=NULL)
-
{
-
delete m_Singleton;
-
}
-
}
-
CSingleton* CSingleton::getSingleton()
-
{
-
if (m_Singleton==NULL)
-
{
-
m_Singleton=new CSingleton;
-
}
-
return m_Singleton;
-
}
-
main.cpp
-
-
-
-
-
int _tmain(int argc, _TCHAR* argv[])
-
{
-
std::cout<<CSingleton::getSingleton()->a;
-
return 0;
-
}
运行之,出现了一个链接错误。如下:
1>Singleton.obj : error LNK2001: 无法解析的外部符号 "private: static class CSingleton * CSingleton::m_Singleton" (?m_Singleton@CSingleton@@0PAV1@A)
1>D:\Microsoft Visual Studio 9.0\Projects\TestCpp\Debug\TestCpp.exe : fatal error LNK1120: 1 个无法解析的外部命令
很尴尬的错误,编译的错误容易找出,但是链接的错误就尴尬了。特别是LNK2001的原因更是五花八门啊。不过还是可以看出是m_Singleton这个地方出现了问题,这是一个静态变量。
了解一下static变量的作用和内部机制就知道为什么会出现这个错误了。
作用:
static是用以控制变量的可见性和存储方式。我们知道,栈上的变量在函数结束后自动释放,而如果分配在堆上又不方便进行控制,如果定义一个全局变量会完全暴露,破坏了它的访问范围,而静态变量可以维持在一定范围内可见。
内部机制:
1.static变量是服务于整个类,而非某一个对象,因此它要求在程序的一开始就已经存在,而不管有没有创建属于该类的对象,因为函数是在程序的运行中被调用的,所以静态变量不能在函数中进行分配空间和初始化。
2.这样一来,它可以进行分配空间就有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。
3.因为类的头文件声明只对变量进行声明,而不会分配空间,所以不能在类的头文件中进行定义。
4.如果在类的头文件声明外进行定义,可能别的类在进行引用时会出现重复定义。
5.静态变量存储在程序的静态存储区上。
6.这里有个例外,如果成员变量是静态常量类型的整数类(如int,char,bool),可以直接在声明中初始化,而无需定义。(From Effective C++)
解决方法
那么,由此我们就可以知道,LINK2001的问题就是m_Singleton没有分配空间。
因此只要在CSingleton.cpp外进行静态变量的定义就可以了。
CSingleton.cpp修改如下,编译链接运行正常。
-
-
-
-
CSingleton* CSingleton::m_Singleton=NULL;//为静态变量m_Singleton分配空间
-
-
CSingleton::CSingleton(void)
-
{
-
a=3;
-
}
-
CSingleton::~CSingleton(void)
-
{
-
if(m_Singleton!=NULL)
-
{
-
delete m_Singleton;
-
}
-
}
-
CSingleton* CSingleton::getSingleton()
-
{
-
if (m_Singleton==NULL)
-
{
-
m_Singleton=new CSingleton;
-
}
-
return m_Singleton;
-
}转自: https://blog.csdn.net/jackystudio/article/details/11482067
今天写一个单例类,在使用静态变量的时候发现了一个之前没有注意到的问题,这里总结并记录一下。
先看这个单例类:
-
Singleton.h
-
-
-
class CSingleton
-
{
-
public:
-
~CSingleton(void);
-
static CSingleton* getSingleton();
-
int a;
-
private:
-
CSingleton(void);
-
static CSingleton* m_Singleton;};
-
Singleton.cpp
-
-
-
-
CSingleton::CSingleton(void)
-
{
-
a=3;
-
}
-
CSingleton::~CSingleton(void)
-
{
-
if(m_Singleton!=NULL)
-
{
-
delete m_Singleton;
-
}
-
}
-
CSingleton* CSingleton::getSingleton()
-
{
-
if (m_Singleton==NULL)
-
{
-
m_Singleton=new CSingleton;
-
}
-
return m_Singleton;
-
}
-
main.cpp
-
-
-
-
-
int _tmain(int argc, _TCHAR* argv[])
-
{
-
std::cout<<CSingleton::getSingleton()->a;
-
return 0;
-
}
运行之,出现了一个链接错误。如下:
1>Singleton.obj : error LNK2001: 无法解析的外部符号 "private: static class CSingleton * CSingleton::m_Singleton" (?m_Singleton@CSingleton@@0PAV1@A)
1>D:\Microsoft Visual Studio 9.0\Projects\TestCpp\Debug\TestCpp.exe : fatal error LNK1120: 1 个无法解析的外部命令
很尴尬的错误,编译的错误容易找出,但是链接的错误就尴尬了。特别是LNK2001的原因更是五花八门啊。不过还是可以看出是m_Singleton这个地方出现了问题,这是一个静态变量。
了解一下static变量的作用和内部机制就知道为什么会出现这个错误了。
作用:
static是用以控制变量的可见性和存储方式。我们知道,栈上的变量在函数结束后自动释放,而如果分配在堆上又不方便进行控制,如果定义一个全局变量会完全暴露,破坏了它的访问范围,而静态变量可以维持在一定范围内可见。
内部机制:
1.static变量是服务于整个类,而非某一个对象,因此它要求在程序的一开始就已经存在,而不管有没有创建属于该类的对象,因为函数是在程序的运行中被调用的,所以静态变量不能在函数中进行分配空间和初始化。
2.这样一来,它可以进行分配空间就有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。
3.因为类的头文件声明只对变量进行声明,而不会分配空间,所以不能在类的头文件中进行定义。
4.如果在类的头文件声明外进行定义,可能别的类在进行引用时会出现重复定义。
5.静态变量存储在程序的静态存储区上。
6.这里有个例外,如果成员变量是静态常量类型的整数类(如int,char,bool),可以直接在声明中初始化,而无需定义。(From Effective C++)
解决方法
那么,由此我们就可以知道,LINK2001的问题就是m_Singleton没有分配空间。
因此只要在CSingleton.cpp外进行静态变量的定义就可以了。
CSingleton.cpp修改如下,编译链接运行正常。
-
-
-
-
CSingleton* CSingleton::m_Singleton=NULL;//为静态变量m_Singleton分配空间
-
-
CSingleton::CSingleton(void)
-
{
-
a=3;
-
}
-
CSingleton::~CSingleton(void)
-
{
-
if(m_Singleton!=NULL)
-
{
-
delete m_Singleton;
-
}
-
}
-
CSingleton* CSingleton::getSingleton()
-
{
-
if (m_Singleton==NULL)
-
{
-
m_Singleton=new CSingleton;
-
}
-
return m_Singleton;
-
}

浙公网安备 33010602011771号