C++静态成员变量为什么在类外部定义?
2014-06-13 22:21
357 查看
c++中静态成员变量要在类外部再定义,否则产生link2001错误.
class testClass
{
public:
static int m_i;
};
// 类外部定义,若不写会产生
// error LNK2001: unresolved external symbol "public: static int testClass::m_i" (?m_i@testClass@@2HA)
int testClass::m_i;
int main(int argc, char* argv[])
{
printf("%d\n",testClass::m_i);
printf("\n");
return 0;
}
为什么要在类的外部进行定义的原因:
1. 在类中,只是声明了静态变量,并没有定义。
2. 声明只是表明了变量的数据类型和属性,并不分配内存;定义则是需要分配内存的。
注意:如果在类里面这么写int a; 那么是既声明了变量,也定义了变量,两者合在一起了。
3. 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“对象(实例)级别”的。
类级别的成员,先于该类任何对象的存在而存在,它被该类所有的对象共享。
4. 现在,咱们假定要实例化该类的一个对象,那么会发生什么事情呢?
静态成员肯定要出现在这个对象里面的,对吧?这时候才去定义那个静态成员吗?这显然是不合适的。
因为,比如有另外一个线程也要创建该类的对象,那么也要按照这个方式去定义那个静态成员。
这会产生两种可能的情况:
A. 重复定义;
B. 就算不产生重复定义的情况,也会产生竞争,从而造成死锁的问题,以至于对象无法创建。
很显然,编译器不能这么干。那么很合理的解决办法,就是事先在类的外部把它定义好,然后再供所有的对象共享。
当然这样做,还是有可能产生线程安全的问题,但不管怎么说对象是创建好了,而这种线程安全问题,可以在编程中予以解决。
对于class的static data member,其实只是声明了一个scope(还记得class::static_data_member中的::么?),
既然是声明而已,所以还需要一个定义,
之所以需要在类的外面,因为本质来说它和global和static变量没什么区别,都是在数据段的,只是scope不一样,属于class而已。
这里反映出了C/C++里面一些稍微偏底层的复杂的细微的概念,比如scope,storage,life time。
::是指scope,是在class里面声明的,
static指storage,是和global一样,在外面定义的。
class testClass
{
public:
static int m_i;
};
// 类外部定义,若不写会产生
// error LNK2001: unresolved external symbol "public: static int testClass::m_i" (?m_i@testClass@@2HA)
int testClass::m_i;
int main(int argc, char* argv[])
{
printf("%d\n",testClass::m_i);
printf("\n");
return 0;
}
为什么要在类的外部进行定义的原因:
1. 在类中,只是声明了静态变量,并没有定义。
2. 声明只是表明了变量的数据类型和属性,并不分配内存;定义则是需要分配内存的。
注意:如果在类里面这么写int a; 那么是既声明了变量,也定义了变量,两者合在一起了。
3. 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“对象(实例)级别”的。
类级别的成员,先于该类任何对象的存在而存在,它被该类所有的对象共享。
4. 现在,咱们假定要实例化该类的一个对象,那么会发生什么事情呢?
静态成员肯定要出现在这个对象里面的,对吧?这时候才去定义那个静态成员吗?这显然是不合适的。
因为,比如有另外一个线程也要创建该类的对象,那么也要按照这个方式去定义那个静态成员。
这会产生两种可能的情况:
A. 重复定义;
B. 就算不产生重复定义的情况,也会产生竞争,从而造成死锁的问题,以至于对象无法创建。
很显然,编译器不能这么干。那么很合理的解决办法,就是事先在类的外部把它定义好,然后再供所有的对象共享。
当然这样做,还是有可能产生线程安全的问题,但不管怎么说对象是创建好了,而这种线程安全问题,可以在编程中予以解决。
对于class的static data member,其实只是声明了一个scope(还记得class::static_data_member中的::么?),
既然是声明而已,所以还需要一个定义,
之所以需要在类的外面,因为本质来说它和global和static变量没什么区别,都是在数据段的,只是scope不一样,属于class而已。
这里反映出了C/C++里面一些稍微偏底层的复杂的细微的概念,比如scope,storage,life time。
::是指scope,是在class里面声明的,
static指storage,是和global一样,在外面定义的。
相关文章推荐
- c++中静态成员变量为什么要在类外部再定义?
- c++中静态成员变量要在类外部再定义,否则产生link2001错误
- c++中静态成员变量要在类外部再定义或初始化的原因
- c++中静态成员变量要在类外部再定义,否则产生link2001错误
- c++中静态成员变量要在类外部再定义,否则产生link2001错误
- c++中静态成员变量要在类外部再定义,否则产生link2001错误.
- VC C++中定义静态成员变量后需要在外部初始化,否则出错
- c++中静态成员变量要在类外部再定义或初始化的原因
- c++中静态成员变量要在类外部再定义,否则产生link2001错误
- 为什么C++中的类不能定义自身类的对象,而java可以? 【转载】
- 匿名内部类使用了一个在其外部定义的对象,为什么编译器会要求其参数引用是final呢
- C++: 为什么我们一般都要将函数的声明和定义分开?(separate the declaration of function from its definition)
- 【c++】为什么类中静态(static)成员不能在类的定义内初始化?
- 关于C++ 类数据成员初始化的一点总结【为什么类定义中不能初始化成员变量】
- C++使用static的错误:无法解析的外部符号、“static”不应在文件范围内定义的成员函数上使用
- c++ 中为什么要定义public protect…
- 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)
- C++为什么需要定义自己的复制构造函数
- 为什么C++静态成员函数不能访问非静态成员变量、不能调用非静态成员函数?(面试常考)
- C++为什么需要定义自己的复制构造函数